diff --git a/packages/client-core/i18n/en/admin.json b/packages/client-core/i18n/en/admin.json index d40aa031d7..d4ca45826f 100755 --- a/packages/client-core/i18n/en/admin.json +++ b/packages/client-core/i18n/en/admin.json @@ -571,6 +571,7 @@ "subtitle": "Edit Metabase Settings", "siteUrl": "Site Url", "secretKey": "Secret Key", + "environment": "Environment", "expiration": "Expiration", "crashDashboardId": "Crash Dashboard Id" }, diff --git a/packages/client-core/i18n/en/editor.json b/packages/client-core/i18n/en/editor.json index cbd6e57567..d02eab69e9 100755 --- a/packages/client-core/i18n/en/editor.json +++ b/packages/client-core/i18n/en/editor.json @@ -72,7 +72,7 @@ "unknownStatus": "Unknown Status", "CORS": "Possibly a CORS error", "urlFetchError": "Failed to fetch \"{{url}}\"", - "invalidSceneName": "Scene name must be 4-64 characters long, using only alphanumeric characters, hyphens, and underscores." + "invalidSceneName": "Scene name must be 4-64 characters long, using only alphanumeric characters and hyphens, and begin and end with an alphanumeric." }, "viewport": { "title": "Viewport", diff --git a/packages/client-core/src/admin/components/settings/tabs/metabase.tsx b/packages/client-core/src/admin/components/settings/tabs/metabase.tsx index 40b4fe6f52..ee76c62584 100644 --- a/packages/client-core/src/admin/components/settings/tabs/metabase.tsx +++ b/packages/client-core/src/admin/components/settings/tabs/metabase.tsx @@ -44,6 +44,7 @@ const MetabaseTab = forwardRef(({ open }: { open: boolean }, ref: React.MutableR const id = useHookstate(undefined) const siteUrl = useHookstate('') const secretKey = useHookstate('') + const environment = useHookstate('') const expiration = useHookstate(10) const crashDashboardId = useHookstate('') const metabaseSettingMutation = useMutation(metabaseSettingPath) @@ -55,6 +56,7 @@ const MetabaseTab = forwardRef(({ open }: { open: boolean }, ref: React.MutableR id.set(data[0].id) siteUrl.set(data[0].siteUrl) secretKey.set(data[0].secretKey) + environment.set(data[0].environment) expiration.set(data[0].expiration) crashDashboardId.set(data[0].crashDashboardId || '') } @@ -63,13 +65,14 @@ const MetabaseTab = forwardRef(({ open }: { open: boolean }, ref: React.MutableR const handleSubmit = (event) => { event.preventDefault() - if (!siteUrl.value || !secretKey.value) return + if (!siteUrl.value || !secretKey.value || !environment.value) return state.loading.set(true) const setting = { siteUrl: siteUrl.value, secretKey: secretKey.value, + environment: environment.value, crashDashboardId: crashDashboardId.value } @@ -90,6 +93,7 @@ const MetabaseTab = forwardRef(({ open }: { open: boolean }, ref: React.MutableR id.set(data[0].id) siteUrl.set(data[0].siteUrl) secretKey.set(data[0].secretKey) + environment.set(data[0].environment) expiration.set(data[0].expiration) crashDashboardId.set(data[0].crashDashboardId || '') } @@ -112,6 +116,13 @@ const MetabaseTab = forwardRef(({ open }: { open: boolean }, ref: React.MutableR onChange={(e) => siteUrl.set(e.target.value)} /> + environment.set(e.target.value)} + /> + void + zE?: (...args: any) => void } } @@ -49,7 +49,7 @@ export const useZendesk = () => { const authenticateUser = () => { if (authenticated.value || config.client.zendesk.authenticationEnabled !== 'true') return - window.zE('messenger', 'loginUser', function (callback: any) { + window.zE?.('messenger', 'loginUser', function (callback: any) { zendeskMutation.create().then(async (token) => { authenticated.set(true) await callback(token) @@ -71,10 +71,10 @@ export const useZendesk = () => { hideWidget() authenticateUser() } - window.zE('messenger:on', 'close', () => { + window.zE?.('messenger:on', 'close', () => { hideWidget() }) - window.zE('messenger:on', 'open', function () { + window.zE?.('messenger:on', 'open', function () { showWidget() }) }) @@ -89,28 +89,28 @@ export const useZendesk = () => { authenticateUser() } else if (user.isGuest.value && initialized.value) { closeChat() - window.zE('messenger', 'logoutUser') + window.zE?.('messenger', 'logoutUser') } }, [user.value]) const hideWidget = () => { if (!initialized.value) return - window.zE('messenger', 'hide') + window.zE?.('messenger', 'hide') isWidgetVisible.set(false) } const showWidget = () => { if (!initialized.value) return - window.zE('messenger', 'show') + window.zE?.('messenger', 'show') isWidgetVisible.set(true) } const openChat = () => { if (!initialized.value) return - window.zE('messenger', 'open') + window.zE?.('messenger', 'open') } const closeChat = () => { if (!initialized.value) return - window.zE('messenger', 'close') + window.zE?.('messenger', 'close') } return { diff --git a/packages/common/src/regex/index.ts b/packages/common/src/regex/index.ts index 610dd4ebc6..2b89670699 100644 --- a/packages/common/src/regex/index.ts +++ b/packages/common/src/regex/index.ts @@ -29,7 +29,7 @@ Ethereal Engine. All Rights Reserved. export const VALID_FILENAME_REGEX = /^(?!.*[\s_<>:"/\\|?*\u0000-\u001F].*)[^\s_<>:"/\\|?*\u0000-\u001F]{1,64}$/ // eslint-disable-next-line no-control-regex export const WINDOWS_RESERVED_NAME_REGEX = /^(con|prn|aux|nul|com\d|lpt\d)$/i -export const VALID_SCENE_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9-]{2,62}[a-zA-Z0-9_\-]$/ +export const VALID_SCENE_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9-]{2,62}[a-zA-Z0-9]$/ export const VALID_HEIRARCHY_SEARCH_REGEX = /[.*+?^${}()|[\]\\]/g /** diff --git a/packages/common/src/schemas/integrations/metabase/metabase-setting.schema.ts b/packages/common/src/schemas/integrations/metabase/metabase-setting.schema.ts index 4877d8a324..cf3f8063c1 100644 --- a/packages/common/src/schemas/integrations/metabase/metabase-setting.schema.ts +++ b/packages/common/src/schemas/integrations/metabase/metabase-setting.schema.ts @@ -40,6 +40,7 @@ export const metabaseSettingSchema = Type.Object( }), siteUrl: Type.String(), secretKey: Type.String(), + environment: Type.String(), crashDashboardId: Type.Optional(Type.String()), expiration: Type.Number(), createdAt: Type.String({ format: 'date-time' }), @@ -70,6 +71,7 @@ export const metabaseSettingQueryProperties = Type.Pick(metabaseSettingSchema, [ 'id', 'siteUrl', 'secretKey', + 'environment', 'crashDashboardId' ]) diff --git a/packages/common/src/schemas/media/file-browser.schema.ts b/packages/common/src/schemas/media/file-browser.schema.ts index 391fae4e59..cd490d4173 100644 --- a/packages/common/src/schemas/media/file-browser.schema.ts +++ b/packages/common/src/schemas/media/file-browser.schema.ts @@ -84,7 +84,8 @@ export const fileBrowserPatchSchema = Type.Intersect( project: Type.String(), body: Type.Any(), // Buffer | string contentType: Type.Optional(Type.String()), - storageProviderName: Type.Optional(Type.String()) + storageProviderName: Type.Optional(Type.String()), + fileName: Type.Optional(Type.String()) }) ], { diff --git a/packages/common/src/schemas/media/invalidation.schema.ts b/packages/common/src/schemas/media/invalidation.schema.ts index 8207d46f4a..fdd8afa4d7 100644 --- a/packages/common/src/schemas/media/invalidation.schema.ts +++ b/packages/common/src/schemas/media/invalidation.schema.ts @@ -48,7 +48,7 @@ export const invalidationSchema = Type.Object( export interface InvalidationType extends Static {} // Schema for creating new entries -export const invalidationDataSchema = Type.Partial(invalidationSchema, { $id: 'InvalidationData' }) +export const invalidationDataSchema = Type.Pick(invalidationSchema, ['path'], { $id: 'InvalidationData' }) export interface InvalidationData extends Static {} // Schema for allowed query properties diff --git a/packages/common/src/schemas/recording/recording.schema.ts b/packages/common/src/schemas/recording/recording.schema.ts index a4a28c3f24..e73ce7344c 100644 --- a/packages/common/src/schemas/recording/recording.schema.ts +++ b/packages/common/src/schemas/recording/recording.schema.ts @@ -69,7 +69,7 @@ export interface RecordingDatabaseType extends Omit { } // Schema for creating new entries -export const recordingDataSchema = Type.Partial(recordingSchema, { +export const recordingDataSchema = Type.Pick(recordingSchema, ['schema'], { $id: 'RecordingData' }) export interface RecordingData extends Static {} @@ -81,7 +81,7 @@ export const recordingPatchSchema = Type.Partial(recordingSchema, { export interface RecordingPatch extends Static {} // Schema for allowed query properties -export const recordingQueryProperties = Type.Pick(recordingSchema, ['id', 'userId']) +export const recordingQueryProperties = Type.Pick(recordingSchema, ['id', 'userId', 'createdAt']) export const recordingQuerySchema = Type.Intersect( [ querySyntax(recordingQueryProperties), diff --git a/packages/editor/src/components/toolbar/Toolbar.tsx b/packages/editor/src/components/toolbar/Toolbar.tsx index 4ecf87012e..798b785122 100644 --- a/packages/editor/src/components/toolbar/Toolbar.tsx +++ b/packages/editor/src/components/toolbar/Toolbar.tsx @@ -34,6 +34,7 @@ import { GLTFModifiedState } from '@etherealengine/engine/src/gltf/GLTFDocumentS import { getMutableState, getState, useHookstate, useMutableState } from '@etherealengine/hyperflux' import { useFind } from '@etherealengine/spatial/src/common/functions/FeathersHooks' import { ContextMenu } from '@etherealengine/ui/src/components/tailwind/ContextMenu' +import { SidebarButton } from '@etherealengine/ui/src/components/tailwind/SidebarButton' import Button from '@etherealengine/ui/src/primitives/tailwind/Button' import { t } from 'i18next' import React from 'react' @@ -201,10 +202,9 @@ export default function Toolbar() {
{toolbarMenu.map(({ name, action, hotkey }, index) => (
- +
))}
diff --git a/packages/engine/src/scene/components/LinkComponent.ts b/packages/engine/src/scene/components/LinkComponent.ts index a4f0dbdd5a..eae4c6238e 100755 --- a/packages/engine/src/scene/components/LinkComponent.ts +++ b/packages/engine/src/scene/components/LinkComponent.ts @@ -73,7 +73,7 @@ export const LinkComponent = defineComponent({ onInit: (entity) => { return { - url: 'https://www.etherealengine.org', + url: '', sceneNav: false, location: '' } diff --git a/packages/server-core/src/integrations/metabase/metabase-setting/metabase-setting.seed.ts b/packages/server-core/src/integrations/metabase/metabase-setting/metabase-setting.seed.ts index bb830a8893..814be9d4c3 100644 --- a/packages/server-core/src/integrations/metabase/metabase-setting/metabase-setting.seed.ts +++ b/packages/server-core/src/integrations/metabase/metabase-setting/metabase-setting.seed.ts @@ -42,6 +42,7 @@ export async function seed(knex: Knex): Promise { { siteUrl: process.env.METABASE_SITE_URL!, secretKey: process.env.METABASE_SECRET_KEY!, + environment: process.env.METABASE_ENVIRONMENT!, crashDashboardId: process.env.METABASE_CRASH_DASHBOARD_ID!, expiration: isNaN(parseInt(process.env.METABASE_EXPIRATION!)) ? 10 : parseInt(process.env.METABASE_EXPIRATION!) } diff --git a/packages/server-core/src/integrations/metabase/metabase-setting/migrations/20240816095000_metabase-environment-column.ts b/packages/server-core/src/integrations/metabase/metabase-setting/migrations/20240816095000_metabase-environment-column.ts new file mode 100644 index 0000000000..391b52006f --- /dev/null +++ b/packages/server-core/src/integrations/metabase/metabase-setting/migrations/20240816095000_metabase-environment-column.ts @@ -0,0 +1,74 @@ +/* +CPAL-1.0 License + +The contents of this file are subject to the Common Public Attribution License +Version 1.0. (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +https://github.com/EtherealEngine/etherealengine/blob/dev/LICENSE. +The License is based on the Mozilla Public License Version 1.1, but Sections 14 +and 15 have been added to cover use of software over a computer network and +provide for limited attribution for the Original Developer. In addition, +Exhibit A has been modified to be consistent with Exhibit B. + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the +specific language governing rights and limitations under the License. + +The Original Code is Ethereal Engine. + +The Original Developer is the Initial Developer. The Initial Developer of the +Original Code is the Ethereal Engine team. + +All portions of the code written by the Ethereal Engine team are Copyright © 2021-2023 +Ethereal Engine. All Rights Reserved. +*/ + +import { metabaseSettingPath } from '@etherealengine/common/src/schemas/integrations/metabase/metabase-setting.schema' +import type { Knex } from 'knex' + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +export async function up(knex: Knex): Promise { + await knex.raw('SET FOREIGN_KEY_CHECKS=0') + + const tableExists = await knex.schema.hasTable(metabaseSettingPath) + if (tableExists) { + const environmentExists = await knex.schema.hasColumn(metabaseSettingPath, 'environment') + if (environmentExists === false) { + await knex.schema.alterTable(metabaseSettingPath, async (table) => { + table.string('environment').nullable() + }) + + const metabaseSettings = await knex.table(metabaseSettingPath).first() + + if (metabaseSettings) { + await knex.table(metabaseSettingPath).update({ + environment: process.env.METABASE_ENVIRONMENT + }) + } + } + } + await knex.raw('SET FOREIGN_KEY_CHECKS=1') +} + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +export async function down(knex: Knex): Promise { + await knex.raw('SET FOREIGN_KEY_CHECKS=0') + + const tableExists = await knex.schema.hasTable(metabaseSettingPath) + if (tableExists) { + const environmentExists = await knex.schema.hasColumn(metabaseSettingPath, 'environment') + if (environmentExists) { + await knex.schema.alterTable(metabaseSettingPath, async (table) => { + table.dropColumn('environment') + }) + } + } + + await knex.raw('SET FOREIGN_KEY_CHECKS=1') +} diff --git a/packages/server-core/src/integrations/metabase/metabase-url/metabase-url.hooks.ts b/packages/server-core/src/integrations/metabase/metabase-url/metabase-url.hooks.ts index 4f5c1f0333..69e1ea8800 100644 --- a/packages/server-core/src/integrations/metabase/metabase-url/metabase-url.hooks.ts +++ b/packages/server-core/src/integrations/metabase/metabase-url/metabase-url.hooks.ts @@ -47,6 +47,7 @@ export const metabaseCrashDashboard = async (context: HookContext schemaHooks.validateData(fileBrowserUpdateValidator)], + update: [schemaHooks.validateData(fileBrowserUpdateValidator)], patch: [ (context) => { context[SYNC] = false return context }, - () => schemaHooks.validateData(fileBrowserPatchValidator) + schemaHooks.validateData(fileBrowserPatchValidator) ], remove: [] }, diff --git a/packages/server-core/src/media/file-browser/file-browser.test.ts b/packages/server-core/src/media/file-browser/file-browser.test.ts index 82681a7901..577ec87280 100644 --- a/packages/server-core/src/media/file-browser/file-browser.test.ts +++ b/packages/server-core/src/media/file-browser/file-browser.test.ts @@ -28,7 +28,7 @@ import assert from 'assert' import { fileBrowserPath } from '@etherealengine/common/src/schemas/media/file-browser.schema' import { destroyEngine } from '@etherealengine/ecs/src/Engine' -import { ProjectType, projectPath } from '@etherealengine/common/src/schema.type.module' +import { ProjectType, projectPath, staticResourcePath } from '@etherealengine/common/src/schema.type.module' import { Application } from '../../../declarations' import { createFeathersKoaApp } from '../../createApp' import { getStorageProvider } from '../storageprovider/storageprovider' @@ -227,18 +227,35 @@ describe('file-browser.test', () => { }) it('copies file', async () => { + const oldPath = 'projects/' + testProjectName2 + '/public/' + const newPath = 'projects/' + testProjectName + '/public/' + const copyFileResult = await app.service(fileBrowserPath).update(null, { oldProject: testProjectName2, newProject: testProjectName, oldName: testFileName2, newName: testFileName2, - oldPath: 'projects/' + testProjectName2 + '/public/', - newPath: 'projects/' + testProjectName + '/public/', + oldPath, + newPath, isCopy: true }) assert.equal(copyFileResult.length, 1) - assert(copyFileResult[0].key === 'projects/' + testProjectName + '/public/' + testFileName2) + assert(copyFileResult[0].key === newPath + testFileName2) + + const originalResource = await app.service(staticResourcePath).find({ + query: { + key: oldPath + testFileName2 + } + }) + assert.ok(originalResource.data.length === 1, 'Original resource not found') + + const copiedResource = await app.service(staticResourcePath).find({ + query: { + key: newPath + testFileName2 + } + }) + assert.ok(copiedResource.data.length === 1, 'Copied resource not found') }) it('copies directory', async () => { diff --git a/packages/server-core/src/media/invalidation/invalidation.hooks.ts b/packages/server-core/src/media/invalidation/invalidation.hooks.ts index e555a2e912..1dec204476 100755 --- a/packages/server-core/src/media/invalidation/invalidation.hooks.ts +++ b/packages/server-core/src/media/invalidation/invalidation.hooks.ts @@ -45,15 +45,12 @@ export default { before: { all: [ disallow('external'), - () => schemaHooks.validateQuery(invalidationQueryValidator), + schemaHooks.validateQuery(invalidationQueryValidator), schemaHooks.resolveQuery(invalidationQueryResolver) ], find: [], get: [], - create: [ - () => schemaHooks.validateData(invalidationDataValidator), - schemaHooks.resolveData(invalidationDataResolver) - ], + create: [schemaHooks.validateData(invalidationDataValidator), schemaHooks.resolveData(invalidationDataResolver)], update: [disallow()], patch: [disallow()], remove: [] diff --git a/packages/server-core/src/projects/project/project-helper.ts b/packages/server-core/src/projects/project/project-helper.ts index fe7121309d..a40a792edd 100644 --- a/packages/server-core/src/projects/project/project-helper.ts +++ b/packages/server-core/src/projects/project/project-helper.ts @@ -1784,9 +1784,15 @@ export const uploadLocalProjectToProvider = async ( const stats = await getStats(fileResult, contentType) const resourceInfo = resourcesJson?.[filePathRelative] const type = isScene ? 'scene' : getResourceType(filePathRelative, resourceInfo!) - const thumbnailKey = - resourceInfo?.thumbnailKey ?? (isScene ? key.split('.').slice(0, -1).join('.') + '.thumbnail.jpg' : undefined) - + let thumbnailKey = resourceInfo?.thumbnailKey + if (!thumbnailKey) { + if (isScene) { + thumbnailKey = key.split('.').slice(0, -1).join('.') + '.thumbnail.jpg' + } else if (type === 'thumbnail') { + //since thumbnails are not in resource json, we need to redefine their thumbnail keys here + thumbnailKey = key + } + } if (existingKeySet.has(key)) { const id = existingKeySet.get(key)! existingKeySet.delete(key) diff --git a/packages/server-core/src/recording/recording-resource/recording-resource.hooks.ts b/packages/server-core/src/recording/recording-resource/recording-resource.hooks.ts index 71ebd5bb77..80189d0970 100755 --- a/packages/server-core/src/recording/recording-resource/recording-resource.hooks.ts +++ b/packages/server-core/src/recording/recording-resource/recording-resource.hooks.ts @@ -50,20 +50,20 @@ export default { before: { all: [ - () => schemaHooks.validateQuery(recordingResourceQueryValidator), + schemaHooks.validateQuery(recordingResourceQueryValidator), schemaHooks.resolveQuery(recordingResourceQueryResolver) ], find: [iff(isProvider('external'), verifyScope('recording', 'read'))], get: [iff(isProvider('external'), verifyScope('recording', 'read'))], create: [ iff(isProvider('external'), verifyScope('recording', 'write'), verifyScope('settings', 'write')), - () => schemaHooks.validateData(recordingResourceDataValidator), + schemaHooks.validateData(recordingResourceDataValidator), schemaHooks.resolveData(recordingResourceDataResolver) ], update: [disallow()], patch: [ iff(isProvider('external'), verifyScope('recording', 'write')), - () => schemaHooks.validateData(recordingResourcePatchValidator), + schemaHooks.validateData(recordingResourcePatchValidator), schemaHooks.resolveData(recordingResourcePatchResolver) ], remove: [iff(isProvider('external'), verifyScope('recording', 'write'))] diff --git a/packages/server-core/src/recording/recording/recording.hooks.ts b/packages/server-core/src/recording/recording/recording.hooks.ts index 2a5f8536af..2c0b94797d 100755 --- a/packages/server-core/src/recording/recording/recording.hooks.ts +++ b/packages/server-core/src/recording/recording/recording.hooks.ts @@ -87,7 +87,7 @@ export default { }, before: { - all: [() => schemaHooks.validateQuery(recordingQueryValidator), schemaHooks.resolveQuery(recordingQueryResolver)], + all: [schemaHooks.validateQuery(recordingQueryValidator), schemaHooks.resolveQuery(recordingQueryResolver)], find: [ iff( isProvider('external'), @@ -100,13 +100,13 @@ export default { create: [ iff(isProvider('external'), verifyScope('recording', 'write')), setLoggedinUserInBody('userId'), - () => schemaHooks.validateData(recordingDataValidator), + schemaHooks.validateData(recordingDataValidator), schemaHooks.resolveData(recordingDataResolver) ], update: [disallow()], patch: [ iff(isProvider('external'), verifyScope('recording', 'write')), - () => schemaHooks.validateData(recordingPatchValidator), + schemaHooks.validateData(recordingPatchValidator), schemaHooks.resolveData(recordingPatchResolver) ], remove: [iff(isProvider('external'), verifyScope('recording', 'write')), ensureRecording] diff --git a/packages/ui/src/components/editor/panels/Assets/container/index.tsx b/packages/ui/src/components/editor/panels/Assets/container/index.tsx index 75977e7330..62de188807 100644 --- a/packages/ui/src/components/editor/panels/Assets/container/index.tsx +++ b/packages/ui/src/components/editor/panels/Assets/container/index.tsx @@ -50,16 +50,18 @@ import { FiRefreshCcw } from 'react-icons/fi' import { HiDotsVertical } from 'react-icons/hi' import { HiMagnifyingGlass, HiOutlineFolder, HiOutlinePlusCircle } from 'react-icons/hi2' import { IoIosArrowDown, IoIosArrowForward } from 'react-icons/io' -import { IoArrowBack } from 'react-icons/io5' +import { IoArrowBack, IoSettingsSharp } from 'react-icons/io5' import { twMerge } from 'tailwind-merge' import Button from '../../../../../primitives/tailwind/Button' import Input from '../../../../../primitives/tailwind/Input' import LoadingView from '../../../../../primitives/tailwind/LoadingView' +import Slider from '../../../../../primitives/tailwind/Slider' import Tooltip from '../../../../../primitives/tailwind/Tooltip' import { ContextMenu } from '../../../../tailwind/ContextMenu' import InfiniteScroll from '../../../../tailwind/InfiniteScroll' +import { Popup } from '../../../../tailwind/Popup' +import InputGroup from '../../../input/Group' import DeleteFileModal from '../../Files/browserGrid/DeleteFileModal' -import { ViewModeSettings } from '../../Files/container' import { FileIcon } from '../../Files/icon' import { FileUploadProgress } from '../../Files/upload/FileUploadProgress' import { AssetIconMap } from '../icons' @@ -125,6 +127,37 @@ function mapCategoriesHelper(collapsedCategories: { [key: string]: boolean }) { return result } +const ViewModeSettings = () => { + const { t } = useTranslation() + + const viewModeSettings = useHookstate(getMutableState(FilesViewModeSettings)) + + return ( + + diff --git a/packages/ui/src/components/tailwind/SidebarButton/index.tsx b/packages/ui/src/components/tailwind/SidebarButton/index.tsx new file mode 100644 index 0000000000..22cddb0dc1 --- /dev/null +++ b/packages/ui/src/components/tailwind/SidebarButton/index.tsx @@ -0,0 +1,36 @@ +/* +CPAL-1.0 License + +The contents of this file are subject to the Common Public Attribution License +Version 1.0. (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +https://github.com/EtherealEngine/etherealengine/blob/dev/LICENSE. +The License is based on the Mozilla Public License Version 1.1, but Sections 14 +and 15 have been added to cover use of software over a computer network and +provide for limited attribution for the Original Developer. In addition, +Exhibit A has been modified to be consistent with Exhibit B. + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the +specific language governing rights and limitations under the License. + +The Original Code is Ethereal Engine. + +The Original Developer is the Initial Developer. The Initial Developer of the +Original Code is the Ethereal Engine team. + +All portions of the code written by the Ethereal Engine team are Copyright © 2021-2023 +Ethereal Engine. All Rights Reserved. +*/ + +import Button from '@etherealengine/ui/src/primitives/tailwind/Button' +import React from 'react' +import { twMerge } from 'tailwind-merge' + +export function SidebarButton({ children, className, ...rest }) { + return ( + + ) +} diff --git a/packages/ui/src/primitives/tailwind/Button/index.tsx b/packages/ui/src/primitives/tailwind/Button/index.tsx index 8daeef8fec..e43206985d 100644 --- a/packages/ui/src/primitives/tailwind/Button/index.tsx +++ b/packages/ui/src/primitives/tailwind/Button/index.tsx @@ -32,7 +32,7 @@ export interface ButtonProps extends React.HTMLAttributes { endIcon?: ReactNode children?: ReactNode size?: 'small' | 'medium' | 'large' - variant?: 'primary' | 'secondary' | 'outline' | 'danger' | 'success' | 'transparent' | 'sidebar' + variant?: 'primary' | 'secondary' | 'outline' | 'danger' | 'success' | 'transparent' disabled?: boolean fullWidth?: boolean rounded?: 'partial' | 'full' | 'none' @@ -59,8 +59,7 @@ const variants = { outline: 'border border-solid border-theme-primary bg-theme-surface-main dark:bg-theme-highlight text-theme-primary', danger: 'bg-red-500', success: 'bg-teal-700', - transparent: 'bg-transparent dark:bg-transparent', - sidebar: 'bg-[#141619]' + transparent: 'bg-transparent dark:bg-transparent' } const Button = React.forwardRef( diff --git a/packages/ui/src/primitives/tailwind/Checkbox/index.tsx b/packages/ui/src/primitives/tailwind/Checkbox/index.tsx index 0471955ebd..bbb2ed64c4 100644 --- a/packages/ui/src/primitives/tailwind/Checkbox/index.tsx +++ b/packages/ui/src/primitives/tailwind/Checkbox/index.tsx @@ -47,7 +47,7 @@ const Checkbox = ({ className, containerClassName, label, value, onChange, disab } return ( -
+
selected: boolean className?: string + labelClassName?: string disabled?: boolean description?: string }) => { @@ -49,7 +51,7 @@ export const RadioRoot = ({