diff --git a/playwright/accordion.spec.ts b/playwright/accordion.spec.ts index d5456215..dfef9c43 100644 --- a/playwright/accordion.spec.ts +++ b/playwright/accordion.spec.ts @@ -2,19 +2,19 @@ import { test, expect } from "@playwright/test"; test("test", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=accordion&", { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes - // Get the first .accordion-item - const accordionItem = page.locator(".accordion-item"); - // Click on the first .accordion-item + // Get the first .dx-accordion-item + const accordionItem = page.locator(".dx-accordion-item"); + // Click on the first .dx-accordion-item const firstAccordionItem = accordionItem.first(); await firstAccordionItem.locator("button").click(); - // Verify that the first .accordion-item is expanded (data-open="true") + // Verify that the first .dx-accordion-item is expanded (data-open="true") await expect(firstAccordionItem).toHaveAttribute("data-open", "true"); - // Click on the second .accordion-item + // Click on the second .dx-accordion-item const secondAccordionItem = accordionItem.nth(1); await secondAccordionItem.locator("button").click(); - // Verify that the second .accordion-item is expanded (data-open="true") + // Verify that the second .dx-accordion-item is expanded (data-open="true") await expect(secondAccordionItem).toHaveAttribute("data-open", "true"); - // Verify the first .accordion-item is collapsed (data-open="false") + // Verify the first .dx-accordion-item is collapsed (data-open="false") await expect(firstAccordionItem).toHaveAttribute("data-open", "false"); }); diff --git a/playwright/alert-dialog.spec.ts b/playwright/alert-dialog.spec.ts index 48e42d8e..f7269044 100644 --- a/playwright/alert-dialog.spec.ts +++ b/playwright/alert-dialog.spec.ts @@ -4,7 +4,7 @@ test('test', async ({ page }) => { await page.goto('http://127.0.0.1:8080/component/?name=alert_dialog&', { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes await page.getByRole('button', { name: 'Show Alert Dialog' }).click(); // Assert the dialog is open - const dialog = page.locator('.alert-dialog-backdrop'); + const dialog = page.locator('.dx-alert-dialog-backdrop'); await expect(dialog).toHaveAttribute('data-state', 'open'); // Assert the cancel button is focused const cancelButton = page.getByRole('button', { name: 'Cancel' }); diff --git a/playwright/avatar.spec.ts b/playwright/avatar.spec.ts index 77ad6bcc..01069ea8 100644 --- a/playwright/avatar.spec.ts +++ b/playwright/avatar.spec.ts @@ -3,13 +3,13 @@ import { test, expect } from "@playwright/test"; test("test", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=avatar&", { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes // Get the avatar element - const avatar = page.locator(".avatar-item").nth(0); + const avatar = page.locator(".dx-avatar-item").nth(0); // Verify the avatar has a loaded image let image = avatar.locator("img"); await expect(image).toHaveAttribute("src", "https://avatars.githubusercontent.com/u/66571940?s=96&v=4"); // Get the third avatar element (Error State - has invalid image URL, shows fallback) - const errorAvatar = page.locator(".avatar-item").nth(2); + const errorAvatar = page.locator(".dx-avatar-item").nth(2); // Verify the error state avatar has fallback text await expect(errorAvatar).toContainText("JK"); }); diff --git a/playwright/calendar.spec.ts b/playwright/calendar.spec.ts index 7be04bfd..5290d3ce 100644 --- a/playwright/calendar.spec.ts +++ b/playwright/calendar.spec.ts @@ -5,16 +5,16 @@ test("test", async ({ page }) => { timeout: 20 * 60 * 1000, }); // Increase timeout to 20 minutes // Find the calendar element - const calendar = page.locator(".calendar").nth(0); + const calendar = page.locator(".dx-calendar").nth(0); // Find the calendar-nav-prev button - const prevButton = calendar.locator(".calendar-nav-prev"); + const prevButton = calendar.locator(".dx-calendar-nav-prev"); // Find the calendar-nav-next button - const nextButton = calendar.locator(".calendar-nav-next"); + const nextButton = calendar.locator(".dx-calendar-nav-next"); // Assert the calendar is displayed await expect(calendar).toBeVisible({ timeout: 30000 }); // Assert the current month is displayed - const currentMonth = calendar.locator(".calendar-month-select"); + const currentMonth = calendar.locator(".dx-calendar-month-select"); let currentMonthText = await currentMonth.inputValue(); // Click the previous button to go to the previous month @@ -31,7 +31,7 @@ test("test", async ({ page }) => { // Move focus to the calendar with tab await page.keyboard.press("Tab"); const focusedDay = calendar.locator( - '.calendar-grid-cell[data-month="current"]:focus' + '.dx-calendar-grid-cell[data-month="current"]:focus' ); // Assert a day is focused const firstDay = focusedDay.first(); @@ -83,9 +83,9 @@ test("year navigation by moving 52 weeks with arrow keys", async ({ page }) => { }); // Find the calendar element - const calendar = page.locator(".calendar").nth(0); - const monthSelect = calendar.locator(".calendar-month-select"); - const yearSelect = calendar.locator(".calendar-year-select"); + const calendar = page.locator(".dx-calendar").nth(0); + const monthSelect = calendar.locator(".dx-calendar-month-select"); + const yearSelect = calendar.locator(".dx-calendar-year-select"); // Assert the calendar is displayed await expect(calendar).toBeVisible({ timeout: 30000 }); @@ -110,7 +110,7 @@ test("year navigation by moving 52 weeks with arrow keys", async ({ page }) => { // Move focus to the calendar manually const firstDay = calendar - .locator('.calendar-grid-cell[data-month="current"]') + .locator('.dx-calendar-grid-cell[data-month="current"]') .first(); await firstDay.focus(); @@ -148,9 +148,9 @@ test("shift + arrow keys navigation", async ({ page }) => { }); // Find the calendar element - const calendar = page.locator(".calendar").nth(0); - const monthSelect = calendar.locator(".calendar-month-select"); - const yearSelect = calendar.locator(".calendar-year-select"); + const calendar = page.locator(".dx-calendar").nth(0); + const monthSelect = calendar.locator(".dx-calendar-month-select"); + const yearSelect = calendar.locator(".dx-calendar-year-select"); // Assert the calendar is displayed await expect(calendar).toBeVisible({ timeout: 30000 }); @@ -163,7 +163,7 @@ test("shift + arrow keys navigation", async ({ page }) => { // Move focus to the calendar const firstDay = calendar - .locator('.calendar-grid-cell[data-month="current"]') + .locator('.dx-calendar-grid-cell[data-month="current"]') .first(); await firstDay.focus(); @@ -199,9 +199,9 @@ async function testArrowKeyNavigation( }); // Find the calendar element - const calendar = page.locator(".calendar").nth(0); - const monthSelect = calendar.locator(".calendar-month-select"); - const yearSelect = calendar.locator(".calendar-year-select"); + const calendar = page.locator(".dx-calendar").nth(0); + const monthSelect = calendar.locator(".dx-calendar-month-select"); + const yearSelect = calendar.locator(".dx-calendar-year-select"); // Assert the calendar is displayed await expect(calendar).toBeVisible({ timeout: 30000 }); @@ -217,13 +217,13 @@ async function testArrowKeyNavigation( // Move focus to the starting day of the current month const startDay = calendar - .locator('.calendar-grid-cell[data-month="current"]') + .locator('.dx-calendar-grid-cell[data-month="current"]') [startPosition](); await startDay.focus(); // Get the focused day selector const focusedDay = calendar.locator( - '.calendar-grid-cell[data-month="current"]:focus' + '.dx-calendar-grid-cell[data-month="current"]:focus' ); // Array to track all days visited diff --git a/playwright/collapsible.spec.ts b/playwright/collapsible.spec.ts index c4b7cd59..0fc4d851 100644 --- a/playwright/collapsible.spec.ts +++ b/playwright/collapsible.spec.ts @@ -2,11 +2,11 @@ import { test, expect } from "@playwright/test"; test("test", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=collapsible&", { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes - // Get the .collapsible-content - const collapsibleContent = page.locator(".collapsible-content"); - // Click on the .collapsible-trigger - const firstCollapsibleTrigger = page.locator(".collapsible-trigger"); + // Get the .dx-collapsible-content + const collapsibleContent = page.locator(".dx-collapsible-content"); + // Click on the .dx-collapsible-trigger + const firstCollapsibleTrigger = page.locator(".dx-collapsible-trigger"); await firstCollapsibleTrigger.click(); - // Verify that the first .collapsible-content is expanded (data-open="true") + // Verify that the first .dx-collapsible-content is expanded (data-open="true") await expect(collapsibleContent.first()).toHaveAttribute("data-open", "true"); }); diff --git a/playwright/context-menu.spec.ts b/playwright/context-menu.spec.ts index 11704b9c..9939103b 100644 --- a/playwright/context-menu.spec.ts +++ b/playwright/context-menu.spec.ts @@ -7,7 +7,7 @@ test('pointer navigation', async ({ page }) => { }); // Assert the context menu is visible - const contextMenu = page.locator('.context-menu-content'); + const contextMenu = page.locator('.dx-context-menu-content'); await expect(contextMenu).toHaveAttribute('data-state', 'open'); // Click on the "Edit" menu item await page.getByRole('menuitem', { name: 'Edit' }).click(); @@ -22,7 +22,7 @@ test('keyboard navigation', async ({ page }) => { }); // Assert the context menu is visible - const contextMenu = page.locator('.context-menu-content'); + const contextMenu = page.locator('.dx-context-menu-content'); await expect(contextMenu).toHaveAttribute('data-state', 'open'); // Hit escape to close the context menu await page.keyboard.press('Escape'); diff --git a/playwright/dialog.spec.ts b/playwright/dialog.spec.ts index bf95f6cb..76982a71 100644 --- a/playwright/dialog.spec.ts +++ b/playwright/dialog.spec.ts @@ -4,7 +4,7 @@ test('test', async ({ page }) => { await page.goto('http://127.0.0.1:8080/component/?name=dialog&', { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes await page.getByRole('button', { name: 'Show Dialog' }).click(); // Assert the dialog is open - const dialog = page.locator('.dialog-backdrop'); + const dialog = page.locator('.dx-dialog-backdrop'); await expect(dialog).toHaveAttribute('data-state', 'open'); // Assert the close button is focused const closeButton = dialog.getByRole('button'); diff --git a/playwright/menubar.spec.ts b/playwright/menubar.spec.ts index f6968265..8df6a8d9 100644 --- a/playwright/menubar.spec.ts +++ b/playwright/menubar.spec.ts @@ -2,7 +2,7 @@ import { test, expect } from "@playwright/test"; test("pointer navigation", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=menubar&", { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes - const fileMenu = page.locator(".menubar-menu").first(); + const fileMenu = page.locator(".dx-menubar-menu").first(); const fileMenuButton = fileMenu.getByRole("menuitem", { name: "File" }); await fileMenuButton.click(); // Assert the menu is open @@ -10,7 +10,7 @@ test("pointer navigation", async ({ page }) => { await expect(fileMenuContent).toHaveAttribute("data-state", "open"); // After the menu is open, hover over the Edit menu item - const editMenu = page.locator(".menubar-menu").nth(1); + const editMenu = page.locator(".dx-menubar-menu").nth(1); const editMenuButton = editMenu.getByRole("menuitem", { name: "Edit" }); await editMenuButton.hover(); // Assert the Edit menu content is open @@ -28,13 +28,13 @@ test("pointer navigation", async ({ page }) => { test("keyboard navigation", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=menubar&", { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes - await page.locator(".menubar").focus(); - const fileMenu = page.locator(".menubar-menu").first(); + await page.locator(".dx-menubar").focus(); + const fileMenu = page.locator(".dx-menubar-menu").first(); const fileMenuButton = fileMenu.getByRole("menuitem", { name: "File" }); // Go right with the keyboard await page.keyboard.press("ArrowRight"); // Assert the focus is on the Edit menu item - const editMenu = page.locator(".menubar-menu").nth(1); + const editMenu = page.locator(".dx-menubar-menu").nth(1); const editMenuButton = editMenu.getByRole("menuitem", { name: "Edit" }); await expect(editMenuButton).toBeFocused(); // Go left with the keyboard diff --git a/playwright/navbar.spec.ts b/playwright/navbar.spec.ts index cff8cc76..986181c1 100644 --- a/playwright/navbar.spec.ts +++ b/playwright/navbar.spec.ts @@ -24,7 +24,7 @@ test('mobile navigation', async ({ page }) => { test('keyboard navigation', async ({ page }) => { await page.goto('http://127.0.0.1:8080/component/?name=navbar&', { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes - await page.locator('.navbar').focus(); + await page.locator('.dx-navbar').focus(); // Go right with the keyboard await page.keyboard.press('ArrowRight'); // Assert the focus is on the information menu item diff --git a/playwright/select.spec.ts b/playwright/select.spec.ts index cb612ebc..a2036e56 100644 --- a/playwright/select.spec.ts +++ b/playwright/select.spec.ts @@ -5,10 +5,10 @@ test("test", async ({ page }) => { timeout: 20 * 60 * 1000, }); // Increase timeout to 20 minutes // Find Select a fruit... - let selectTrigger = page.locator(".select-trigger"); + let selectTrigger = page.locator(".dx-select-trigger"); await selectTrigger.click(); // Assert the select menu is open - const selectMenu = page.locator(".select-list"); + const selectMenu = page.locator(".dx-select-list"); await expect(selectMenu).toHaveAttribute("data-state", "open"); // Assert the menu is focused @@ -64,10 +64,10 @@ test("test", async ({ page }) => { test("tabbing out of menu closes the select menu", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=select&"); // Find Select a fruit... - let selectTrigger = page.locator(".select-trigger"); + let selectTrigger = page.locator(".dx-select-trigger"); await selectTrigger.click(); // Assert the select menu is open - const selectMenu = page.locator(".select-list"); + const selectMenu = page.locator(".dx-select-list"); await expect(selectMenu).toHaveAttribute("data-state", "open"); // Assert the menu is focused @@ -80,10 +80,10 @@ test("tabbing out of menu closes the select menu", async ({ page }) => { test("tabbing out of item closes the select menu", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=select&"); // Find Select a fruit... - let selectTrigger = page.locator(".select-trigger"); + let selectTrigger = page.locator(".dx-select-trigger"); await selectTrigger.click(); // Assert the select menu is open - const selectMenu = page.locator(".select-list"); + const selectMenu = page.locator(".dx-select-list"); await expect(selectMenu).toHaveAttribute("data-state", "open"); // Assert the menu is focused @@ -101,10 +101,10 @@ test("tabbing out of item closes the select menu", async ({ page }) => { test("options selected", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=select&"); // Find Select a fruit... - let selectTrigger = page.locator(".select-trigger"); + let selectTrigger = page.locator(".dx-select-trigger"); await selectTrigger.click(); // Assert the select menu is open - const selectMenu = page.locator(".select-list"); + const selectMenu = page.locator(".dx-select-list"); await expect(selectMenu).toHaveAttribute("data-state", "open"); // Assert no items have aria-selected @@ -130,8 +130,8 @@ test("options selected", async ({ page }) => { test("down arrow selects first element", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=select&"); // Find Select a fruit... - let selectTrigger = page.locator(".select-trigger"); - const selectMenu = page.locator(".select-list"); + let selectTrigger = page.locator(".dx-select-trigger"); + const selectMenu = page.locator(".dx-select-list"); await selectTrigger.focus(); // Select the first option @@ -143,8 +143,8 @@ test("down arrow selects first element", async ({ page }) => { test("up arrow selects last element", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=select&"); // Find Select a fruit... - let selectTrigger = page.locator(".select-trigger"); - const selectMenu = page.locator(".select-list"); + let selectTrigger = page.locator(".dx-select-trigger"); + const selectMenu = page.locator(".dx-select-list"); await selectTrigger.focus(); // Select the first option diff --git a/playwright/sheet.spec.ts b/playwright/sheet.spec.ts index f0e51595..42d61f6d 100644 --- a/playwright/sheet.spec.ts +++ b/playwright/sheet.spec.ts @@ -7,7 +7,7 @@ test('sheet basic interactions', async ({ page }) => { await page.getByRole('button', { name: 'Right' }).click(); // Assert the sheet is open - const sheet = page.locator('.sheet-root'); + const sheet = page.locator('.dx-sheet-root'); await expect(sheet).toHaveAttribute('data-state', 'open'); // Assert the first input is focused (focus trap) @@ -29,7 +29,7 @@ test('sheet basic interactions', async ({ page }) => { await expect(cancelButton).toBeFocused(); await page.keyboard.press('Tab'); - const closeButton = sheet.locator('.sheet-close'); + const closeButton = sheet.locator('.dx-sheet-close'); await expect(closeButton).toBeFocused(); // Tab again should cycle back to first input @@ -52,7 +52,7 @@ test('sheet basic interactions', async ({ page }) => { test('sheet opens from different sides', async ({ page }) => { await page.goto('http://127.0.0.1:8080/component/?name=sheet&', { timeout: 20 * 60 * 1000 }); - const sheet = page.locator('.sheet-root'); + const sheet = page.locator('.dx-sheet-root'); const sheetContent = page.locator('[data-slot="sheet-content"]'); // Test Top diff --git a/playwright/sidebar.spec.ts b/playwright/sidebar.spec.ts index fc960890..a8cea86a 100644 --- a/playwright/sidebar.spec.ts +++ b/playwright/sidebar.spec.ts @@ -7,7 +7,7 @@ async function gotoSidebarBlock(page: Page) { timeout: 20 * 60 * 1000, }); - await expect(page.locator(".sidebar-wrapper")).toBeVisible(); + await expect(page.locator(".dx-sidebar-wrapper")).toBeVisible(); } test("sidebar: preview page renders block", async ({ page }) => { @@ -31,14 +31,14 @@ test("sidebar: preview page renders block", async ({ page }) => { throw new Error("Sidebar preview iframe has no content frame"); } - await expect(frame.locator(".sidebar-wrapper")).toBeVisible(); + await expect(frame.locator(".dx-sidebar-wrapper")).toBeVisible(); }); test.describe("sidebar: block route", () => { test("desktop: toggles via button and Ctrl+B", async ({ page }) => { await gotoSidebarBlock(page); - const sidebar = page.locator(".sidebar-desktop"); + const sidebar = page.locator(".dx-sidebar-desktop"); await expect(sidebar).toHaveAttribute("data-state", "expanded"); const trigger = page.locator('[data-slot="sidebar-trigger"]'); await expect(trigger).toHaveAccessibleName("Toggle Sidebar"); @@ -59,7 +59,7 @@ test.describe("sidebar: block route", () => { test("desktop: side switch updates data-side", async ({ page }) => { await gotoSidebarBlock(page); - const sidebar = page.locator(".sidebar-desktop"); + const sidebar = page.locator(".dx-sidebar-desktop"); await expect(sidebar).toHaveAttribute("data-side", "left"); await page.getByRole("button", { name: "Right" }).click(); @@ -73,7 +73,7 @@ test.describe("sidebar: block route", () => { }) => { await gotoSidebarBlock(page); - const sidebar = page.locator(".sidebar-desktop"); + const sidebar = page.locator(".dx-sidebar-desktop"); const trigger = page.locator('[data-slot="sidebar-trigger"]'); await page.getByRole("button", { name: "Icon" }).click(); @@ -106,7 +106,7 @@ test.describe("sidebar: block route", () => { const trigger = page.locator('[data-slot="sidebar-trigger"]'); await trigger.tap(); - const sheet = page.locator(".sheet-root"); + const sheet = page.locator(".dx-sheet-root"); await expect(sheet).toHaveAttribute("data-state", "open"); await page.keyboard.press("Escape"); await expect(sheet).toHaveCount(0); diff --git a/playwright/slider.spec.ts b/playwright/slider.spec.ts index 10fa9565..4c832d16 100644 --- a/playwright/slider.spec.ts +++ b/playwright/slider.spec.ts @@ -1,9 +1,9 @@ import { test, expect } from '@playwright/test'; test('test', async ({ page }) => { - await page.goto('http://127.0.0.1:8080/component/block?name=slider&variant=main&', { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes - const slider = page.locator('.slider'); - const thumb = slider.locator('.slider-thumb'); + await page.goto('http://127.0.0.1:8080/component/?name=slider&', { timeout: 20 * 60 * 1000 }); // Increase timeout to 20 minutes + const slider = await page.locator('.dx-slider'); + const thumb = await page.locator('.dx-slider-thumb'); // The initial aria-valuenow should be 50 await expect(thumb).toHaveAttribute('aria-valuenow', '50'); await thumb.focus(); diff --git a/playwright/style-isolation.spec.ts b/playwright/style-isolation.spec.ts new file mode 100644 index 00000000..8391dd0c --- /dev/null +++ b/playwright/style-isolation.spec.ts @@ -0,0 +1,338 @@ +import { test, expect } from "@playwright/test"; + +/** + * Style Isolation Tests + * + * These tests verify that component styles are properly scoped with the `dx-` prefix + * and that external CSS conflicts do not affect component appearance. + */ + +test.describe("Style Isolation", () => { + test("button component resists external CSS conflicts", async ({ page }) => { + await page.goto("http://127.0.0.1:8080/component/?name=button&", { + timeout: 20 * 60 * 1000, + }); + + // Wait for the component to load + const button = page.locator(".dx-button").first(); + await expect(button).toBeVisible({ timeout: 30000 }); + + // Capture original computed styles + const originalStyles = await button.evaluate((el) => { + const styles = getComputedStyle(el); + return { + backgroundColor: styles.backgroundColor, + color: styles.color, + padding: styles.padding, + borderRadius: styles.borderRadius, + }; + }); + + // Inject conflicting CSS targeting generic class names (without dx- prefix) + await page.addStyleTag({ + content: ` + .button { + background-color: red !important; + color: yellow !important; + padding: 100px !important; + border-radius: 0 !important; + } + `, + }); + + // Wait a moment for styles to apply + await page.waitForTimeout(100); + + // Verify the dx-prefixed component is unaffected + const afterStyles = await button.evaluate((el) => { + const styles = getComputedStyle(el); + return { + backgroundColor: styles.backgroundColor, + color: styles.color, + padding: styles.padding, + borderRadius: styles.borderRadius, + }; + }); + + // The dx-button should not be affected by .button styles + expect(afterStyles.backgroundColor).toBe(originalStyles.backgroundColor); + expect(afterStyles.color).toBe(originalStyles.color); + expect(afterStyles.padding).toBe(originalStyles.padding); + expect(afterStyles.borderRadius).toBe(originalStyles.borderRadius); + }); + + test("checkbox component resists external CSS conflicts", async ({ page }) => { + await page.goto("http://127.0.0.1:8080/component/?name=checkbox&", { + timeout: 20 * 60 * 1000, + }); + + // Wait for the component to load + const checkbox = page.locator(".dx-checkbox").first(); + await expect(checkbox).toBeVisible({ timeout: 30000 }); + + // Capture original computed styles + const originalStyles = await checkbox.evaluate((el) => { + const styles = getComputedStyle(el); + return { + width: styles.width, + height: styles.height, + borderRadius: styles.borderRadius, + }; + }); + + // Inject conflicting CSS targeting generic class names + await page.addStyleTag({ + content: ` + .checkbox { + width: 500px !important; + height: 500px !important; + border-radius: 0 !important; + } + `, + }); + + // Wait a moment for styles to apply + await page.waitForTimeout(100); + + // Verify the dx-prefixed component is unaffected + const afterStyles = await checkbox.evaluate((el) => { + const styles = getComputedStyle(el); + return { + width: styles.width, + height: styles.height, + borderRadius: styles.borderRadius, + }; + }); + + expect(afterStyles.width).toBe(originalStyles.width); + expect(afterStyles.height).toBe(originalStyles.height); + expect(afterStyles.borderRadius).toBe(originalStyles.borderRadius); + }); + + test("slider component resists external CSS conflicts", async ({ page }) => { + await page.goto("http://127.0.0.1:8080/component/?name=slider&", { + timeout: 20 * 60 * 1000, + }); + + // Wait for the component to load + const slider = page.locator(".dx-slider").first(); + await expect(slider).toBeVisible({ timeout: 30000 }); + + // Capture original computed styles + const originalStyles = await slider.evaluate((el) => { + const styles = getComputedStyle(el); + return { + height: styles.height, + backgroundColor: styles.backgroundColor, + }; + }); + + // Inject conflicting CSS targeting generic class names + await page.addStyleTag({ + content: ` + .slider { + height: 500px !important; + background-color: red !important; + } + .slider-track { + height: 500px !important; + } + .slider-thumb { + width: 500px !important; + height: 500px !important; + } + `, + }); + + // Wait a moment for styles to apply + await page.waitForTimeout(100); + + // Verify the dx-prefixed component is unaffected + const afterStyles = await slider.evaluate((el) => { + const styles = getComputedStyle(el); + return { + height: styles.height, + backgroundColor: styles.backgroundColor, + }; + }); + + expect(afterStyles.height).toBe(originalStyles.height); + expect(afterStyles.backgroundColor).toBe(originalStyles.backgroundColor); + }); + + test("dialog component resists external CSS conflicts", async ({ page }) => { + await page.goto("http://127.0.0.1:8080/component/?name=dialog&", { + timeout: 20 * 60 * 1000, + }); + + // Open the dialog + await page.getByRole("button", { name: "Show Dialog" }).click(); + + // Wait for the dialog to appear + const dialog = page.locator(".dx-dialog-backdrop"); + await expect(dialog).toHaveAttribute("data-state", "open"); + + const dialogContent = page.locator(".dx-dialog-content").first(); + await expect(dialogContent).toBeVisible(); + + // Capture original computed styles + const originalStyles = await dialogContent.evaluate((el) => { + const styles = getComputedStyle(el); + return { + backgroundColor: styles.backgroundColor, + padding: styles.padding, + borderRadius: styles.borderRadius, + }; + }); + + // Inject conflicting CSS targeting generic class names + await page.addStyleTag({ + content: ` + .dialog { + background-color: red !important; + padding: 500px !important; + } + .dialog-content { + background-color: green !important; + padding: 500px !important; + border-radius: 0 !important; + } + .dialog-backdrop { + background-color: yellow !important; + } + `, + }); + + // Wait a moment for styles to apply + await page.waitForTimeout(100); + + // Verify the dx-prefixed component is unaffected + const afterStyles = await dialogContent.evaluate((el) => { + const styles = getComputedStyle(el); + return { + backgroundColor: styles.backgroundColor, + padding: styles.padding, + borderRadius: styles.borderRadius, + }; + }); + + expect(afterStyles.backgroundColor).toBe(originalStyles.backgroundColor); + expect(afterStyles.padding).toBe(originalStyles.padding); + expect(afterStyles.borderRadius).toBe(originalStyles.borderRadius); + }); + + test("all component classes use dx- prefix", async ({ page }) => { + // List of components to check + const components = [ + "button", + "checkbox", + "slider", + "dialog", + "accordion", + "tabs", + "calendar", + "select", + "menubar", + "tooltip", + ]; + + for (const component of components) { + await page.goto(`http://127.0.0.1:8080/component/?name=${component}&`, { + timeout: 20 * 60 * 1000, + }); + + // Wait for component to load + await page.waitForTimeout(1000); + + // Find all elements with class attributes and verify dx- prefix + const unprefixedClasses = await page.evaluate(() => { + const elements = document.querySelectorAll("[class]"); + const problematicClasses: string[] = []; + + // List of known app-level classes that don't need dx- prefix + const allowedUnprefixed = [ + "component-demo", + "component-preview", + "preview-frame", + "recycle-list-card", + "recycle-list-container", + "recycle-list-demo", + "recycle-list-subtitle", + ]; + + elements.forEach((el) => { + const classes = el.className.split(" "); + classes.forEach((cls) => { + // Skip if it's: + // - already prefixed with dx- + // - an allowed unprefixed class + // - doesn't look like a component class (no hyphens or too short) + if ( + cls.startsWith("dx-") || + allowedUnprefixed.includes(cls) || + !cls.includes("-") || + cls.length < 3 + ) { + return; + } + + // Check if this looks like a component class (has hyphen, not a utility) + // Common component patterns: button-primary, slider-thumb, dialog-content + const componentPatterns = [ + /^(button|checkbox|slider|dialog|accordion|tabs|calendar|select|menubar|tooltip|avatar|badge|card|navbar|sheet|sidebar|popover|progress|radio|switch|textarea|toggle)-/, + ]; + + if (componentPatterns.some((pattern) => pattern.test(cls))) { + problematicClasses.push(cls); + } + }); + }); + + return [...new Set(problematicClasses)]; + }); + + // No component classes should be found without dx- prefix + expect( + unprefixedClasses, + `Component ${component} has unprefixed classes: ${unprefixedClasses.join(", ")}` + ).toHaveLength(0); + } + }); + + test("accordion animations use dx- prefixed keyframes", async ({ page }) => { + await page.goto("http://127.0.0.1:8080/component/?name=accordion&", { + timeout: 20 * 60 * 1000, + }); + + // Wait for component to load + const accordionItem = page.locator(".dx-accordion-item").first(); + await expect(accordionItem).toBeVisible({ timeout: 30000 }); + + // Inject conflicting keyframes with unprefixed names + await page.addStyleTag({ + content: ` + @keyframes accordion-slide-down { + from { height: 0; } + to { height: 9999px; } + } + @keyframes accordion-slide-up { + from { height: 9999px; } + to { height: 0; } + } + `, + }); + + // Open accordion + await accordionItem.locator("button").click(); + await expect(accordionItem).toHaveAttribute("data-open", "true"); + + // The accordion content should animate properly despite conflicting keyframes + const content = accordionItem.locator(".dx-accordion-content").first(); + await expect(content).toBeVisible(); + + // Verify the height is reasonable (not 9999px from the injected keyframes) + const height = await content.evaluate((el) => el.offsetHeight); + expect(height).toBeLessThan(500); + expect(height).toBeGreaterThan(0); + }); +}); diff --git a/playwright/tabs.spec.ts b/playwright/tabs.spec.ts index 26a30035..05a69cf8 100644 --- a/playwright/tabs.spec.ts +++ b/playwright/tabs.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from "@playwright/test"; test("test", async ({ page }) => { await page.goto("http://127.0.0.1:8080/component/?name=tabs&"); let activeTab = page.locator( - "#component-preview-frame > .tabs > .tabs-content[data-state='active']", + "#component-preview-frame > .dx-tabs > .dx-tabs-content[data-state='active']", ); let tab1Button = page.getByRole("tab", { name: "Tab 1" }); let tab2Button = page.getByRole("tab", { name: "Tab 2" }); diff --git a/playwright/tooltip.spec.ts b/playwright/tooltip.spec.ts index 542780a7..5c54692c 100644 --- a/playwright/tooltip.spec.ts +++ b/playwright/tooltip.spec.ts @@ -12,7 +12,7 @@ test("test", async ({ page }) => { await expect(tooltip).toHaveCount(0); // hovering over the trigger element should show the tooltip - await page.locator(".tooltip-trigger").hover(); + await page.locator(".dx-tooltip-trigger").hover(); await expect(tooltip).toBeVisible(); // moving the mouse away from the trigger element should hide the tooltip diff --git a/preview/assets/dx-components-theme.css b/preview/assets/dx-components-theme.css index c55ca4a6..70d80c97 100644 --- a/preview/assets/dx-components-theme.css +++ b/preview/assets/dx-components-theme.css @@ -1,15 +1,6 @@ -/* This file contains the global styles for the styled dioxus components. You only +/* This file contains the theme variables for the styled dioxus components. You only * need to import this file once in your project root. */ -@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"); - -body { - color: var(--secondary-color-4); - font-family: Inter, sans-serif; - font-optical-sizing: auto; - font-style: normal; - font-weight: 400; -} html[data-theme="dark"] { --dark: initial; diff --git a/preview/assets/main.css b/preview/assets/main.css index 6d21cb86..325ee05d 100644 --- a/preview/assets/main.css +++ b/preview/assets/main.css @@ -1,3 +1,6 @@ +/* Typography */ +@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"); + /* Theme style variables */ :root { --highlight-color-main: #dd7230; @@ -16,6 +19,11 @@ body { padding: 0; margin: 0; background-color: var(--primary-color); + color: var(--secondary-color-4); + font-family: Inter, sans-serif; + font-optical-sizing: auto; + font-style: normal; + font-weight: 400; } .dark-mode-only { diff --git a/preview/src/components/accordion/component.rs b/preview/src/components/accordion/component.rs index 67a5f02f..4f88b9ec 100644 --- a/preview/src/components/accordion/component.rs +++ b/preview/src/components/accordion/component.rs @@ -8,7 +8,7 @@ pub fn Accordion(props: AccordionProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } accordion::Accordion { - class: "accordion", + class: "dx-accordion", width: "15rem", id: props.id, allow_multiple_open: props.allow_multiple_open, @@ -25,7 +25,7 @@ pub fn Accordion(props: AccordionProps) -> Element { pub fn AccordionItem(props: AccordionItemProps) -> Element { rsx! { accordion::AccordionItem { - class: "accordion-item", + class: "dx-accordion-item", disabled: props.disabled, default_open: props.default_open, on_change: props.on_change, @@ -41,12 +41,12 @@ pub fn AccordionItem(props: AccordionItemProps) -> Element { pub fn AccordionTrigger(props: AccordionTriggerProps) -> Element { rsx! { accordion::AccordionTrigger { - class: "accordion-trigger", + class: "dx-accordion-trigger", id: props.id, attributes: props.attributes, {props.children} svg { - class: "accordion-expand-icon", + class: "dx-accordion-expand-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", polyline { points: "6 9 12 15 18 9" } @@ -59,7 +59,8 @@ pub fn AccordionTrigger(props: AccordionTriggerProps) -> Element { pub fn AccordionContent(props: AccordionContentProps) -> Element { rsx! { accordion::AccordionContent { - class: "accordion-content", + class: "dx-accordion-content", + style: "--collapsible-content-width: 140px", id: props.id, attributes: props.attributes, {props.children} diff --git a/preview/src/components/accordion/style.css b/preview/src/components/accordion/style.css index 7dd93c3f..6d0dde78 100644 --- a/preview/src/components/accordion/style.css +++ b/preview/src/components/accordion/style.css @@ -1,4 +1,4 @@ -.accordion-trigger { +.dx-accordion-trigger { display: flex; width: 100%; box-sizing: border-box; @@ -15,47 +15,47 @@ text-align: left; } -.accordion-trigger:focus-visible { +.dx-accordion-trigger:focus-visible { border: none; box-shadow: inset 0 0 0 2px var(--focused-border-color); } -.accordion-trigger:hover { +.dx-accordion-trigger:hover { cursor: pointer; text-decoration-line: underline; } -.accordion-content { +.dx-accordion-content { display: grid; } -.accordion-content > * { +.dx-accordion-content > * { overflow: hidden; min-height: 0; } -.accordion-content[data-open="false"] { - animation: accordion-close 300ms cubic-bezier(0.87, 0, 0.13, 1) forwards; +.dx-accordion-content[data-open="false"] { + animation: dx-accordion-slide-down 300ms cubic-bezier(0.87, 0, 0.13, 1) forwards; } -.accordion-content[data-open="true"] { - animation: accordion-open 300ms cubic-bezier(0.87, 0, 0.13, 1) forwards; +.dx-accordion-content[data-open="true"] { + animation: dx-accordion-slide-up 300ms cubic-bezier(0.87, 0, 0.13, 1) forwards; } -@keyframes accordion-close { - from { - grid-template-rows: 1fr; - } +@keyframes dx-accordion-slide-down { + from { + height: var(--collapsible-content-width); + } to { grid-template-rows: 0fr; } } -@keyframes accordion-open { - from { - grid-template-rows: 0fr; - } +@keyframes dx-accordion-slide-up { + from { + height: 0; + } to { grid-template-rows: 1fr; @@ -66,22 +66,22 @@ contain: inline-size; } -.accordion-item { +.dx-accordion-item { overflow: hidden; box-sizing: border-box; border-bottom: 1px solid var(--primary-color-6); margin-top: 1px; } -.accordion-item:first-child { +.dx-accordion-item:first-child { margin-top: 0; } -.accordion-item:last-child { +.dx-accordion-item:last-child { border-bottom: none; } -.accordion-expand-icon { +.dx-accordion-expand-icon { width: 20px; height: 20px; fill: none; @@ -92,6 +92,6 @@ transition: rotate 300ms cubic-bezier(0.4, 0, 0.2, 1); } -.accordion-item[data-open="true"] .accordion-expand-icon { +.dx-accordion-item[data-open="true"] .dx-accordion-expand-icon { rotate: 180deg; } diff --git a/preview/src/components/alert_dialog/component.rs b/preview/src/components/alert_dialog/component.rs index 2cd3c2b0..0b68529d 100644 --- a/preview/src/components/alert_dialog/component.rs +++ b/preview/src/components/alert_dialog/component.rs @@ -10,7 +10,7 @@ pub fn AlertDialogRoot(props: AlertDialogRootProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } alert_dialog::AlertDialogRoot { - class: "alert-dialog-backdrop", + class: "dx-alert-dialog-backdrop", id: props.id, default_open: props.default_open, open: props.open, @@ -26,7 +26,7 @@ pub fn AlertDialogContent(props: AlertDialogContentProps) -> Element { rsx! { alert_dialog::AlertDialogContent { id: props.id, - class: props.class.unwrap_or_default() + " alert-dialog", + class: props.class.unwrap_or_default() + " dx-alert-dialog", attributes: props.attributes, {props.children} } @@ -46,7 +46,7 @@ pub fn AlertDialogDescription(props: AlertDialogDescriptionProps) -> Element { #[component] pub fn AlertDialogActions(props: AlertDialogActionsProps) -> Element { rsx! { - alert_dialog::AlertDialogActions { class: "alert-dialog-actions", attributes: props.attributes, {props.children} } + alert_dialog::AlertDialogActions { class: "dx-alert-dialog-actions", attributes: props.attributes, {props.children} } } } @@ -55,7 +55,7 @@ pub fn AlertDialogCancel(props: AlertDialogCancelProps) -> Element { rsx! { alert_dialog::AlertDialogCancel { on_click: props.on_click, - class: "alert-dialog-cancel", + class: "dx-alert-dialog-cancel", attributes: props.attributes, {props.children} } @@ -66,7 +66,7 @@ pub fn AlertDialogCancel(props: AlertDialogCancelProps) -> Element { pub fn AlertDialogAction(props: AlertDialogActionProps) -> Element { rsx! { alert_dialog::AlertDialogAction { - class: "alert-dialog-action", + class: "dx-alert-dialog-action", on_click: props.on_click, attributes: props.attributes, {props.children} diff --git a/preview/src/components/alert_dialog/style.css b/preview/src/components/alert_dialog/style.css index c89d62ba..c176cd73 100644 --- a/preview/src/components/alert_dialog/style.css +++ b/preview/src/components/alert_dialog/style.css @@ -1,16 +1,16 @@ /* Alert Dialog Backdrop */ -.alert-dialog-backdrop { +.dx-alert-dialog-backdrop { position: fixed; z-index: 1000; background: rgb(0 0 0 / 30%); inset: 0; } -.alert-dialog-backdrop[data-state="closed"] { - animation: alert-animate-out 150ms ease-in forwards; +.dx-alert-dialog-backdrop[data-state="closed"] { + animation: dx-alert-animate-out 150ms ease-in forwards; } -@keyframes alert-animate-out { +@keyframes dx-alert-animate-out { 0% { opacity: 1; transform: scale(1) translateY(0); @@ -22,11 +22,11 @@ } } -.alert-dialog-backdrop[data-state="open"] { - animation: alert-animate-in 150ms ease-out forwards; +.dx-alert-dialog-backdrop[data-state="open"] { + animation: dx-alert-animate-in 150ms ease-out forwards; } -@keyframes alert-animate-in { +@keyframes dx-alert-animate-in { 0% { opacity: 0; transform: scale(0.95) translateY(-2px); @@ -39,7 +39,7 @@ } /* Alert Dialog Container - improved for theme consistency */ -.alert-dialog { +.dx-alert-dialog { position: fixed; z-index: 1001; top: 50%; @@ -64,38 +64,38 @@ transform: translate(-50%, -50%); } -.alert-dialog-title { +.dx-alert-dialog-title { margin: 0; color: var(--secondary-color-4); font-size: 1.25rem; font-weight: 700; } -.alert-dialog-description { +.dx-alert-dialog-description { margin: 0; color: var(--secondary-color-5); font-size: 1rem; } -.alert-dialog-actions { +.dx-alert-dialog-actions { display: flex; flex-direction: column-reverse; gap: 12px; } @media (width >= 40rem) { - .alert-dialog-actions { + .dx-alert-dialog-actions { flex-direction: row; justify-content: flex-end; } - .alert-dialog { + .dx-alert-dialog { max-width: 32rem; text-align: left; } } -.alert-dialog-cancel { +.dx-alert-dialog-cancel { padding: 8px 18px; border: 1px solid var(--primary-color-6); border-radius: 0.5rem; @@ -107,15 +107,15 @@ transition: background-color 0.2s ease; } -.alert-dialog-cancel:hover { +.dx-alert-dialog-cancel:hover { background-color: var(--primary-color-4); } -.alert-dialog-cancel:focus-visible { +.dx-alert-dialog-cancel:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } -.alert-dialog-action { +.dx-alert-dialog-action { padding: 8px 18px; border: 1px solid var(--primary-error-color); border-radius: 0.5rem; @@ -126,10 +126,10 @@ transition: background-color 0.2s ease; } -.alert-dialog-action:hover { +.dx-alert-dialog-action:hover { background-color: var(--secondary-error-color); } -.alert-dialog-action:focus-visible { +.dx-alert-dialog-action:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } diff --git a/preview/src/components/aspect_ratio/style.css b/preview/src/components/aspect_ratio/style.css index 5f31ab1c..5501a570 100644 --- a/preview/src/components/aspect_ratio/style.css +++ b/preview/src/components/aspect_ratio/style.css @@ -1,11 +1,11 @@ -.aspect-ratio-container { +.dx-aspect-ratio-container { overflow: hidden; box-sizing: border-box; padding: 1rem; border-radius: .5rem; } -.aspect-ratio-image { +.dx-aspect-ratio-image { width: 100%; height: 100%; object-fit: cover; diff --git a/preview/src/components/avatar/component.rs b/preview/src/components/avatar/component.rs index 8cf019ba..49b55703 100644 --- a/preview/src/components/avatar/component.rs +++ b/preview/src/components/avatar/component.rs @@ -12,9 +12,9 @@ pub enum AvatarImageSize { impl AvatarImageSize { fn to_class(self) -> &'static str { match self { - AvatarImageSize::Small => "avatar-sm", - AvatarImageSize::Medium => "avatar-md", - AvatarImageSize::Large => "avatar-lg", + AvatarImageSize::Small => "dx-avatar-sm", + AvatarImageSize::Medium => "dx-avatar-md", + AvatarImageSize::Large => "dx-avatar-lg", } } } @@ -29,8 +29,8 @@ pub enum AvatarShape { impl AvatarShape { fn to_class(self) -> &'static str { match self { - AvatarShape::Circle => "avatar-circle", - AvatarShape::Rounded => "avatar-rounded", + AvatarShape::Circle => "dx-avatar-circle", + AvatarShape::Rounded => "dx-avatar-rounded", } } } @@ -70,7 +70,7 @@ pub fn Avatar(props: AvatarProps) -> Element { document::Link { rel: "stylesheet", href: asset!("./style.css") } avatar::Avatar { - class: "avatar {props.size.to_class()} {props.shape.to_class()}", + class: "dx-avatar {props.size.to_class()} {props.shape.to_class()}", on_load: props.on_load, on_error: props.on_error, on_state_change: props.on_state_change, @@ -84,7 +84,7 @@ pub fn Avatar(props: AvatarProps) -> Element { pub fn AvatarImage(props: AvatarImageProps) -> Element { rsx! { avatar::AvatarImage { - class: "avatar-image", + class: "dx-avatar-image", src: props.src, alt: props.alt, attributes: props.attributes, @@ -95,6 +95,6 @@ pub fn AvatarImage(props: AvatarImageProps) -> Element { #[component] pub fn AvatarFallback(props: AvatarFallbackProps) -> Element { rsx! { - avatar::AvatarFallback { class: "avatar-fallback", attributes: props.attributes, {props.children} } + avatar::AvatarFallback { class: "dx-avatar-fallback", attributes: props.attributes, {props.children} } } } diff --git a/preview/src/components/avatar/style.css b/preview/src/components/avatar/style.css index d239e02e..7be49931 100644 --- a/preview/src/components/avatar/style.css +++ b/preview/src/components/avatar/style.css @@ -1,18 +1,18 @@ -.avatar-item { +.dx-avatar-item { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; } -.avatar-label { +.dx-avatar-label { margin: 0; color: var(--secondary-color-4); font-size: 0.875rem; } /* Avatar Component Styles */ -.avatar { +.dx-avatar { position: relative; display: inline-flex; overflow: hidden; @@ -26,50 +26,50 @@ font-weight: 500; } -.avatar-image { +.dx-avatar-image { width: 100%; height: 100%; aspect-ratio: 1; } /* Avatar sizes */ -.avatar-sm { +.dx-avatar-sm { width: 2rem; height: 2rem; font-size: 0.875rem; } -.avatar-md { +.dx-avatar-md { width: 3rem; height: 3rem; font-size: 1.25rem; } -.avatar-lg { +.dx-avatar-lg { width: 4rem; height: 4rem; font-size: 1.75rem; } /* Avatar shape */ -.avatar-circle { +.dx-avatar-circle { border-radius: 50%; } -.avatar-rounded { +.dx-avatar-rounded { border-radius: 8px; } /* State-specific styles */ -.avatar[data-state="loading"] { - animation: pulse 1.5s infinite ease-in-out; +.dx-avatar[data-state="loading"] { + animation: dx-pulse 1.5s infinite ease-in-out; } -.avatar[data-state="empty"] { +.dx-avatar[data-state="empty"] { background: var(--primary-color-7); } -@keyframes pulse { +@keyframes dx-pulse { 0% { opacity: 1; } @@ -83,7 +83,7 @@ } } -.avatar-fallback { +.dx-avatar-fallback { display: flex; width: 100%; height: 100%; @@ -94,7 +94,7 @@ font-size: 1.5rem; } -.avatar[data-state="error"] .avatar-fallback { +.dx-avatar[data-state="error"] .dx-avatar-fallback { background: var(--primary-color-3); color: var(--secondary-color-4); } diff --git a/preview/src/components/avatar/variants/main/mod.rs b/preview/src/components/avatar/variants/main/mod.rs index 7c69da77..328acf8f 100644 --- a/preview/src/components/avatar/variants/main/mod.rs +++ b/preview/src/components/avatar/variants/main/mod.rs @@ -11,8 +11,8 @@ pub fn Demo() -> Element { align_items: "center", justify_content: "between", gap: "1rem", - div { class: "avatar-item", - p { class: "avatar-label", "Basic Usage" } + div { class: "dx-avatar-item", + p { class: "dx-avatar-label", "Basic Usage" } Avatar { size: AvatarImageSize::Small, on_state_change: move |state| { @@ -20,15 +20,15 @@ pub fn Demo() -> Element { }, aria_label: "Basic avatar", AvatarImage { - class: "avatar-image", + class: "dx-avatar-image", src: "https://avatars.githubusercontent.com/u/66571940?s=96&v=4", alt: "User avatar", } - AvatarFallback { class: "avatar-fallback", "EA" } + AvatarFallback { class: "dx-avatar-fallback", "EA" } } } - div { class: "avatar-item", - p { class: "avatar-label", "Rounded" } + div { class: "dx-avatar-item", + p { class: "dx-avatar-label", "Rounded" } Avatar { size: AvatarImageSize::Small, shape: AvatarShape::Rounded, @@ -37,15 +37,15 @@ pub fn Demo() -> Element { }, aria_label: "Basic avatar", AvatarImage { - class: "avatar-image", + class: "dx-avatar-image", src: "https://avatars.githubusercontent.com/u/66571940?s=96&v=4", alt: "User avatar", } - AvatarFallback { class: "avatar-fallback", "EA" } + AvatarFallback { class: "dx-avatar-fallback", "EA" } } } - div { class: "avatar-item", - p { class: "avatar-label", "Error State" } + div { class: "dx-avatar-item", + p { class: "dx-avatar-label", "Error State" } Avatar { size: AvatarImageSize::Medium, on_state_change: move |state| { @@ -53,15 +53,15 @@ pub fn Demo() -> Element { }, aria_label: "Error avatar", AvatarImage { - class: "avatar-image", + class: "dx-avatar-image", src: "https://invalid-url.example/image.jpg", alt: "Invalid image", } - AvatarFallback { class: "avatar-fallback", "JK" } + AvatarFallback { class: "dx-avatar-fallback", "JK" } } } - div { class: "avatar-item", - p { class: "avatar-label", "Large Size" } + div { class: "dx-avatar-item", + p { class: "dx-avatar-label", "Large Size" } Avatar { size: AvatarImageSize::Large, on_state_change: move |state| { @@ -69,11 +69,11 @@ pub fn Demo() -> Element { }, aria_label: "Large avatar", AvatarImage { - class: "avatar-image", + class: "dx-avatar-image", src: asset!("/assets/dioxus-logo.png", ImageAssetOptions::new().with_avif()), alt: "Large avatar", } - AvatarFallback { class: "avatar-fallback", "DX" } + AvatarFallback { class: "dx-avatar-fallback", "DX" } } } } diff --git a/preview/src/components/badge/component.rs b/preview/src/components/badge/component.rs index 83115056..473be6c2 100644 --- a/preview/src/components/badge/component.rs +++ b/preview/src/components/badge/component.rs @@ -53,7 +53,7 @@ pub fn Badge(props: BadgeProps) -> Element { fn BadgeElement(props: BadgeProps) -> Element { rsx! { span { - class: "badge", + class: "dx-badge", "data-style": props.variant.class(), ..props.attributes, {props.children} diff --git a/preview/src/components/badge/style.css b/preview/src/components/badge/style.css index e36df538..0b18dc16 100644 --- a/preview/src/components/badge/style.css +++ b/preview/src/components/badge/style.css @@ -1,10 +1,10 @@ -.badge-example { +.dx-badge-example { display: flex; align-items: center; gap: 1rem; } -.badge { +.dx-badge { display: inline-flex; min-width: 20px; height: 20px; @@ -16,27 +16,27 @@ gap: 4px } -.badge[padding="true"] { +.dx-badge[padding="true"] { padding: 0 8px; } -.badge[data-style="primary"] { +.dx-badge[data-style="primary"] { background-color: var(--secondary-color-2); color: var(--primary-color); } -.badge[data-style="secondary"] { +.dx-badge[data-style="secondary"] { background-color: var(--primary-color-5); color: var(--secondary-color-1); } -.badge[data-style="outline"] { +.dx-badge[data-style="outline"] { border: 1px solid var(--primary-color-6); background-color: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3)); color: var(--secondary-color-4); } -.badge[data-style="destructive"] { +.dx-badge[data-style="destructive"] { background-color: var(--primary-error-color); color: var(--contrast-error-color); -} \ No newline at end of file +} diff --git a/preview/src/components/button/component.rs b/preview/src/components/button/component.rs index e057876c..3f851049 100644 --- a/preview/src/components/button/component.rs +++ b/preview/src/components/button/component.rs @@ -37,7 +37,7 @@ pub fn Button( children: Element, ) -> Element { let base = attributes!(button { - class: "button", + class: "dx-button", "data-style": variant.class(), }); let merged = merge_attributes(vec![base, attributes]); diff --git a/preview/src/components/button/style.css b/preview/src/components/button/style.css index 2f0d9ed6..d4c5077d 100644 --- a/preview/src/components/button/style.css +++ b/preview/src/components/button/style.css @@ -1,4 +1,4 @@ -.button { +.dx-button { padding: 8px 18px; border: none; border-radius: 0.5rem; @@ -7,54 +7,54 @@ transition: background-color 0.2s ease, color 0.2s ease; } -.button:focus-visible { +.dx-button:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } -.button[data-style="primary"] { +.dx-button[data-style="primary"] { background-color: var(--secondary-color-2); color: var(--primary-color); } -.button[data-style="primary"]:hover { +.dx-button[data-style="primary"]:hover { background-color: var(--secondary-color-1); } -.button[data-style="secondary"] { +.dx-button[data-style="secondary"] { background-color: var(--primary-color-5); color: var(--secondary-color-1); } -.button[data-style="secondary"]:hover { +.dx-button[data-style="secondary"]:hover { background-color: var(--primary-color-4); } -.button[data-style="ghost"] { +.dx-button[data-style="ghost"] { background-color: transparent; color: var(--secondary-color-4); } -.button[data-style="ghost"]:hover { +.dx-button[data-style="ghost"]:hover { background-color: var(--primary-color-5); color: var(--secondary-color-1); } -.button[data-style="outline"] { +.dx-button[data-style="outline"] { border: 1px solid var(--primary-color-6); background-color: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3)); color: var(--secondary-color-4); } -.button[data-style="outline"]:hover { +.dx-button[data-style="outline"]:hover { background-color: var(--primary-color-4); } -.button[data-style="destructive"] { +.dx-button[data-style="destructive"] { background-color: var(--primary-error-color); color: var(--contrast-error-color); } -.button[data-style="destructive"]:hover { +.dx-button[data-style="destructive"]:hover { background-color: var(--secondary-error-color); } diff --git a/preview/src/components/calendar/component.rs b/preview/src/components/calendar/component.rs index 70354c49..f084e035 100644 --- a/preview/src/components/calendar/component.rs +++ b/preview/src/components/calendar/component.rs @@ -10,7 +10,7 @@ pub fn Calendar(props: CalendarProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } calendar::Calendar { - class: "calendar", + class: "dx-calendar", selected_date: props.selected_date, on_date_change: props.on_date_change, on_format_weekday: props.on_format_weekday, @@ -35,7 +35,7 @@ pub fn RangeCalendar(props: RangeCalendarProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } calendar::RangeCalendar { - class: "calendar", + class: "dx-calendar", selected_range: props.selected_range, on_range_change: props.on_range_change, on_format_weekday: props.on_format_weekday, @@ -62,7 +62,7 @@ pub fn CalendarView( ) -> Element { rsx! { div { - class: "calendar-view", + class: "dx-calendar-view", ..attributes, {children} } @@ -90,7 +90,7 @@ pub fn CalendarPreviousMonthButton( rsx! { calendar::CalendarPreviousMonthButton { attributes, svg { - class: "calendar-previous-month-icon", + class: "dx-calendar-previous-month-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", polyline { points: "15 6 9 12 15 18" } @@ -106,7 +106,7 @@ pub fn CalendarNextMonthButton( rsx! { calendar::CalendarNextMonthButton { attributes, svg { - class: "calendar-next-month-icon", + class: "dx-calendar-next-month-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", polyline { points: "9 18 15 12 9 6" } @@ -118,14 +118,14 @@ pub fn CalendarNextMonthButton( #[component] pub fn CalendarSelectMonth(props: CalendarSelectMonthProps) -> Element { rsx! { - calendar::CalendarSelectMonth { class: "calendar-month-select", attributes: props.attributes } + calendar::CalendarSelectMonth { class: "dx-calendar-month-select", attributes: props.attributes } } } #[component] pub fn CalendarSelectYear(props: CalendarSelectYearProps) -> Element { rsx! { - calendar::CalendarSelectYear { class: "calendar-year-select", attributes: props.attributes } + calendar::CalendarSelectYear { class: "dx-calendar-year-select", attributes: props.attributes } } } diff --git a/preview/src/components/calendar/style.css b/preview/src/components/calendar/style.css index af0fa324..02c4d715 100644 --- a/preview/src/components/calendar/style.css +++ b/preview/src/components/calendar/style.css @@ -1,5 +1,5 @@ /* Calendar Container */ -.calendar { +.dx-calendar { display: flex; flex-direction: row; border: 1px solid var(--primary-color-6); @@ -12,7 +12,7 @@ } /* Calendar Navigation */ -.calendar-navigation { +.dx-calendar-navigation { position: relative; display: flex; align-items: center; @@ -22,14 +22,14 @@ gap: 0.5rem; } -.calendar-nav-title { +.dx-calendar-nav-title { color: var(--secondary-color-4); font-size: 16px; font-weight: 600; } -.calendar-nav-prev, -.calendar-nav-next { +.dx-calendar-nav-prev, +.dx-calendar-nav-next { position: absolute; display: flex; width: 1.75rem; @@ -45,35 +45,35 @@ font-size: 1rem; } -.calendar-nav-prev { +.dx-calendar-nav-prev { left: 0.75rem; } -.calendar-nav-next { +.dx-calendar-nav-next { right: 0.75rem; } -.calendar-nav-prev:hover, -.calendar-nav-next:hover { +.dx-calendar-nav-prev:hover, +.dx-calendar-nav-next:hover { border-color: var(--primary-color-7); background-color: var(--primary-color-4); color: var(--secondary-color-4); } -.calendar-nav-prev:focus-visible, -.calendar-nav-next:focus-visible { +.dx-calendar-nav-prev:focus-visible, +.dx-calendar-nav-next:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } -.calendar-nav-prev:disabled, -.calendar-nav-next:disabled { +.dx-calendar-nav-prev:disabled, +.dx-calendar-nav-next:disabled { border-color: var(--primary-color-5); background-color: var(--primary-color-2); color: var(--secondary-color-3); cursor: not-allowed; } -.calendar-month-title { +.dx-calendar-month-title { display: flex; width: 100%; height: 1.75rem; @@ -82,23 +82,23 @@ } /* Calendar Grid */ -.calendar-view { +.dx-calendar-view { display: flex; flex-direction: column; } -.calendar-grid { +.dx-calendar-grid { width: 100%; padding: 0.5rem; } -.calendar-grid-header { +.dx-calendar-grid-header { display: flex; flex-direction: row; margin-bottom: 8px; } -.calendar-grid-day-header { +.dx-calendar-grid-day-header { flex: 1; color: var(--secondary-color-5); font-size: 12px; @@ -106,14 +106,14 @@ text-align: center; } -.calendar-grid-body { +.dx-calendar-grid-body { display: flex; width: 100%; flex-direction: column; gap: 0.25rem; } -.calendar-grid-cell { +.dx-calendar-grid-cell { width: 2rem; border: none; border-radius: 0.5rem; @@ -124,67 +124,67 @@ font-size: 14px; } -.calendar-grid-cell[data-month="current"]:not([data-disabled="true"]):hover { +.dx-calendar-grid-cell[data-month="current"]:not([data-disabled="true"]):hover { background-color: var(--primary-color-4); } -.calendar-grid-cell[data-month="current"]:focus-visible { +.dx-calendar-grid-cell[data-month="current"]:focus-visible { outline: 2px solid var(--focused-border-color); outline-offset: 2px; } -.calendar-grid-cell[data-month="last"], -.calendar-grid-cell[data-month="next"], -.calendar-grid-cell[data-disabled="true"] { +.dx-calendar-grid-cell[data-month="last"], +.dx-calendar-grid-cell[data-month="next"], +.dx-calendar-grid-cell[data-disabled="true"] { color: var(--secondary-color-5); cursor: not-allowed; } -.calendar-grid-cell[data-month="last"][data-selected="true"], -.calendar-grid-cell[data-month="next"][data-selected="true"] { +.dx-calendar-grid-cell[data-month="last"][data-selected="true"], +.dx-calendar-grid-cell[data-month="next"][data-selected="true"] { background-color: var(--secondary-color-6); } -.calendar-grid-cell[data-month="current"][data-selected="true"] { +.dx-calendar-grid-cell[data-month="current"][data-selected="true"] { background-color: var(--secondary-color-2); color: var(--primary-color); } -.calendar-grid-cell[data-month="current"][data-unavailable="true"] { +.dx-calendar-grid-cell[data-month="current"][data-unavailable="true"] { color: var(--secondary-color-6); cursor: not-allowed; text-decoration: line-through; } -.calendar-grid-week td { +.dx-calendar-grid-week td { padding-right: 0; padding-left: 0; } -.calendar-grid-week td:first-child .calendar-grid-cell { +.dx-calendar-grid-week td:first-child .dx-calendar-grid-cell { border-bottom-left-radius: 0.5rem; border-top-left-radius: 0.5rem; } -.calendar-grid-week td:last-child .calendar-grid-cell { +.dx-calendar-grid-week td:last-child .dx-calendar-grid-cell { border-bottom-right-radius: 0.5rem; border-top-right-radius: 0.5rem; } -.calendar-grid-cell[data-month="last"][data-selection-between="true"], -.calendar-grid-cell[data-month="next"][data-selection-between="true"] { +.dx-calendar-grid-cell[data-month="last"][data-selection-between="true"], +.dx-calendar-grid-cell[data-month="next"][data-selection-between="true"] { border-radius: 0; background-color: var(--primary-color-5); color: var(--secondary-color-5); } -.calendar-grid-cell[data-month="current"][data-selection-between="true"] { +.dx-calendar-grid-cell[data-month="current"][data-selection-between="true"] { border-radius: 0; background-color: var(--primary-color-5); color: var(--secondary-color-4); } -td:has(.calendar-grid-cell[data-selection-start="true"]) { +td:has(.dx-calendar-grid-cell[data-selection-start="true"]) { padding: 0; margin-top: 1px; margin-bottom: 1px; @@ -193,7 +193,7 @@ td:has(.calendar-grid-cell[data-selection-start="true"]) { border-top-left-radius: 0.5rem; } -td:has(.calendar-grid-cell[data-selection-end="true"]) { +td:has(.dx-calendar-grid-cell[data-selection-end="true"]) { padding: 0; margin-top: 1px; margin-bottom: 1px; @@ -202,7 +202,7 @@ td:has(.calendar-grid-cell[data-selection-end="true"]) { border-top-right-radius: 0.5rem; } -.calendar-grid-cell[data-month="current"][data-selected="true"]:hover { +.dx-calendar-grid-cell[data-month="current"][data-selected="true"]:hover { background-color: var(--light, var(--secondary-color-2)) var(--dark, var(--primary-color-5)); color: var(--light, var(--primary-color)) @@ -210,13 +210,13 @@ td:has(.calendar-grid-cell[data-selection-end="true"]) { font-weight: var(--light, 550) var(--dark, inherit); } -.calendar-grid-cell[data-month="current"][data-today="true"]:not( +.dx-calendar-grid-cell[data-month="current"][data-today="true"]:not( [data-selected="true"] ) { background-color: var(--primary-color-5); } -.calendar-grid-weeknum { +.dx-calendar-grid-weeknum { border-radius: 0.5rem; background-color: var(--primary-color); color: var(--secondary-color-5); @@ -224,7 +224,7 @@ td:has(.calendar-grid-cell[data-selection-end="true"]) { } /* Calendar with week numbers */ -.calendar-grid-week { +.dx-calendar-grid-week { display: flex; width: 100%; flex-direction: row; @@ -232,13 +232,13 @@ td:has(.calendar-grid-cell[data-selection-end="true"]) { } /* Calendar states */ -.calendar[data-disabled="true"] { +.dx-calendar[data-disabled="true"] { opacity: 0.6; pointer-events: none; } -.calendar-next-month-icon, -.calendar-previous-month-icon { +.dx-calendar-next-month-icon, +.dx-calendar-previous-month-icon { width: 20px; height: 20px; fill: none; @@ -248,19 +248,19 @@ td:has(.calendar-grid-cell[data-selection-end="true"]) { stroke-width: 2; } -.calendar-month-select-container, -.calendar-year-select-container { +.dx-calendar-month-select-container, +.dx-calendar-year-select-container { position: relative; } -.calendar-month-select-container:has(:focus-visible), -.calendar-year-select-container:has(:focus-visible) { +.dx-calendar-month-select-container:has(:focus-visible), +.dx-calendar-year-select-container:has(:focus-visible) { border-radius: 0.5rem; outline: 2px solid var(--focused-border-color); } -.calendar-month-select, -.calendar-year-select { +.dx-calendar-month-select, +.dx-calendar-year-select { position: absolute; width: 100%; height: 100%; @@ -270,8 +270,8 @@ td:has(.calendar-grid-cell[data-selection-end="true"]) { opacity: 0; } -.calendar-month-select-value, -.calendar-year-select-value { +.dx-calendar-month-select-value, +.dx-calendar-year-select-value { display: inline-flex; align-items: center; justify-content: center; @@ -286,7 +286,7 @@ td:has(.calendar-grid-cell[data-selection-end="true"]) { color 0.2s ease; } -.select-expand-icon { +.dx-select-expand-icon { width: 20px; height: 20px; fill: none; @@ -294,4 +294,4 @@ td:has(.calendar-grid-cell[data-selection-end="true"]) { stroke-linecap: round; stroke-linejoin: round; stroke-width: 2; -} \ No newline at end of file +} diff --git a/preview/src/components/card/component.rs b/preview/src/components/card/component.rs index 036749a7..37ac085a 100644 --- a/preview/src/components/card/component.rs +++ b/preview/src/components/card/component.rs @@ -8,7 +8,7 @@ pub fn Card( rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } div { - class: "card", + class: "dx-card", "data-slot": "card", ..attributes, {children} @@ -23,7 +23,7 @@ pub fn CardHeader( ) -> Element { rsx! { div { - class: "card-header", + class: "dx-card-header", "data-slot": "card-header", ..attributes, {children} @@ -38,7 +38,7 @@ pub fn CardTitle( ) -> Element { rsx! { div { - class: "card-title", + class: "dx-card-title", "data-slot": "card-title", ..attributes, {children} @@ -53,7 +53,7 @@ pub fn CardDescription( ) -> Element { rsx! { div { - class: "card-description", + class: "dx-card-description", "data-slot": "card-description", ..attributes, {children} @@ -68,7 +68,7 @@ pub fn CardAction( ) -> Element { rsx! { div { - class: "card-action", + class: "dx-card-action", "data-slot": "card-action", ..attributes, {children} @@ -83,7 +83,7 @@ pub fn CardContent( ) -> Element { rsx! { div { - class: "card-content", + class: "dx-card-content", "data-slot": "card-content", ..attributes, {children} @@ -98,7 +98,7 @@ pub fn CardFooter( ) -> Element { rsx! { div { - class: "card-footer", + class: "dx-card-footer", "data-slot": "card-footer", ..attributes, {children} diff --git a/preview/src/components/card/style.css b/preview/src/components/card/style.css index 2ad7e6e6..79db7d00 100644 --- a/preview/src/components/card/style.css +++ b/preview/src/components/card/style.css @@ -1,4 +1,4 @@ -.card { +.dx-card { display: flex; flex-direction: column; padding: 1.5rem 0; @@ -10,7 +10,7 @@ gap: 1.5rem; } -.card-header { +.dx-card-header { display: grid; align-items: start; padding: 0 1.5rem; @@ -19,33 +19,33 @@ grid-template-rows: auto auto; } -.card-header:has([data-slot="card-action"]) { +.dx-card-header:has([data-slot="card-action"]) { grid-template-columns: 1fr auto; } -.card-title { +.dx-card-title { font-size: 1rem; font-weight: 600; line-height: 1; } -.card-description { +.dx-card-description { color: var(--secondary-color-5); font-size: 0.875rem; line-height: 1.25rem; } -.card-action { +.dx-card-action { grid-column-start: 2; grid-row: 1 / span 2; place-self: start end; } -.card-content { +.dx-card-content { padding: 0 1.5rem; } -.card-footer { +.dx-card-footer { display: flex; align-items: center; padding: 0 1.5rem; diff --git a/preview/src/components/checkbox/component.rs b/preview/src/components/checkbox/component.rs index 782cb193..6fae9c20 100644 --- a/preview/src/components/checkbox/component.rs +++ b/preview/src/components/checkbox/component.rs @@ -6,7 +6,7 @@ pub fn Checkbox(props: CheckboxProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } checkbox::Checkbox { - class: "checkbox", + class: "dx-checkbox", checked: props.checked, default_checked: props.default_checked, required: props.required, @@ -15,9 +15,9 @@ pub fn Checkbox(props: CheckboxProps) -> Element { value: props.value, on_checked_change: props.on_checked_change, attributes: props.attributes, - checkbox::CheckboxIndicator { class: "checkbox-indicator", + checkbox::CheckboxIndicator { class: "dx-checkbox-indicator", svg { - class: "checkbox-check-icon", + class: "dx-checkbox-check-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", path { d: "M5 13l4 4L19 7" } diff --git a/preview/src/components/checkbox/style.css b/preview/src/components/checkbox/style.css index 5d236a34..b64d62f7 100644 --- a/preview/src/components/checkbox/style.css +++ b/preview/src/components/checkbox/style.css @@ -1,4 +1,4 @@ -.checkbox { +.dx-checkbox { width: 1rem; height: 1rem; box-sizing: border-box; @@ -12,23 +12,23 @@ cursor: pointer; } -.checkbox-indicator { +.dx-checkbox-indicator { display: flex; align-items: center; justify-content: center; } -.checkbox[data-state="checked"] { +.dx-checkbox[data-state="checked"] { background-color: var(--secondary-color-2); box-shadow: none; color: var(--primary-color); } -.checkbox:focus-visible { +.dx-checkbox:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } -.checkbox-check-icon { +.dx-checkbox-check-icon { width: 1rem; height: 1rem; fill: none; diff --git a/preview/src/components/collapsible/component.rs b/preview/src/components/collapsible/component.rs index 1dcc75fa..24cfde5d 100644 --- a/preview/src/components/collapsible/component.rs +++ b/preview/src/components/collapsible/component.rs @@ -17,7 +17,7 @@ pub fn Collapsible(props: CollapsibleProps) -> Element { on_open_change: props.on_open_change, as: props.r#as, attributes: props.attributes, - class: "collapsible", + class: "dx-collapsible", {props.children} } } @@ -25,7 +25,7 @@ pub fn Collapsible(props: CollapsibleProps) -> Element { #[component] pub fn CollapsibleTrigger(props: CollapsibleTriggerProps) -> Element { - let base = attributes!(button { class: "collapsible-trigger" }); + let base = attributes!(button { class: "dx-collapsible-trigger" }); let merged = merge_attributes(vec![base, props.attributes]); let show_icon = props.r#as.is_none(); @@ -35,7 +35,7 @@ pub fn CollapsibleTrigger(props: CollapsibleTriggerProps) -> Element { {props.children} if show_icon { svg { - class: "collapsible-expand-icon", + class: "dx-collapsible-expand-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", // shifted up by 6 polyline { points: "6 9 12 15 18 9" } @@ -52,7 +52,7 @@ pub fn CollapsibleTrigger(props: CollapsibleTriggerProps) -> Element { pub fn CollapsibleContent(props: CollapsibleContentProps) -> Element { rsx! { collapsible::CollapsibleContent { - class: "collapsible-content", + class: "dx-collapsible-content", id: props.id, attributes: props.attributes, {props.children} diff --git a/preview/src/components/collapsible/style.css b/preview/src/components/collapsible/style.css index f9c0d538..95296cc5 100644 --- a/preview/src/components/collapsible/style.css +++ b/preview/src/components/collapsible/style.css @@ -1,4 +1,4 @@ -.collapsible-trigger { +.dx-collapsible-trigger { display: flex; overflow: hidden; width: 100%; @@ -16,20 +16,20 @@ text-align: left; } -.collapsible-trigger:focus-visible { +.dx-collapsible-trigger:focus-visible { box-shadow: inset 0 0 0 2px var(--focused-border-color); } -.collapsible-trigger:hover { +.dx-collapsible-trigger:hover { cursor: pointer; text-decoration-line: underline; } -.collapsible-content { +.dx-collapsible-content { display: contents; } -.collapsible-expand-icon { +.dx-collapsible-expand-icon { width: 1rem; height: 1rem; fill: none; diff --git a/preview/src/components/context_menu/component.rs b/preview/src/components/context_menu/component.rs index 2855722e..af87421a 100644 --- a/preview/src/components/context_menu/component.rs +++ b/preview/src/components/context_menu/component.rs @@ -40,7 +40,7 @@ pub fn ContextMenuTrigger(props: ContextMenuTriggerProps) -> Element { pub fn ContextMenuContent(props: ContextMenuContentProps) -> Element { rsx! { context_menu::ContextMenuContent { - class: "context-menu-content", + class: "dx-context-menu-content", id: props.id, attributes: props.attributes, {props.children} @@ -52,7 +52,7 @@ pub fn ContextMenuContent(props: ContextMenuContentProps) -> Element { pub fn ContextMenuItem(props: ContextMenuItemProps) -> Element { rsx! { context_menu::ContextMenuItem { - class: "context-menu-item", + class: "dx-context-menu-item", disabled: props.disabled, value: props.value, index: props.index, diff --git a/preview/src/components/context_menu/style.css b/preview/src/components/context_menu/style.css index 3ad0a91a..3ab73ede 100644 --- a/preview/src/components/context_menu/style.css +++ b/preview/src/components/context_menu/style.css @@ -1,4 +1,4 @@ -.context-menu-content { +.dx-context-menu-content { z-index: 1000; min-width: 220px; padding: 0.25rem; @@ -12,11 +12,11 @@ will-change: transform, opacity; } -.context-menu-content[data-state="closed"] { - animation: context-menu-animate-out 150ms ease-in forwards; +.dx-context-menu-content[data-state="closed"] { + animation: dx-context-menu-animate-out 150ms ease-in forwards; } -@keyframes context-menu-animate-out { +@keyframes dx-context-menu-animate-out { 0% { opacity: 1; transform: scale(1) translateY(0); @@ -28,11 +28,11 @@ } } -.context-menu-content[data-state="open"] { - animation: context-menu-animate-in 150ms ease-out forwards; +.dx-context-menu-content[data-state="open"] { + animation: dx-context-menu-animate-in 150ms ease-out forwards; } -@keyframes context-menu-animate-in { +@keyframes dx-context-menu-animate-in { 0% { opacity: 0; transform: scale(0.95) translateY(-2px); @@ -44,7 +44,7 @@ } } -.context-menu-item { +.dx-context-menu-item { display: flex; align-items: center; padding: 8px 12px; @@ -57,13 +57,13 @@ user-select: none; } -.context-menu-item[data-disabled="true"] { +.dx-context-menu-item[data-disabled="true"] { color: var(--secondary-color-5); cursor: not-allowed; } -.context-menu-item:hover:not([data-disabled="true"]), -.context-menu-item:focus-visible { +.dx-context-menu-item:hover:not([data-disabled="true"]), +.dx-context-menu-item:focus-visible { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-7)); color: var(--light, var(--secondary-color-1)) diff --git a/preview/src/components/date_picker/component.rs b/preview/src/components/date_picker/component.rs index a1bd04f3..423ffee1 100644 --- a/preview/src/components/date_picker/component.rs +++ b/preview/src/components/date_picker/component.rs @@ -15,7 +15,7 @@ pub fn DatePicker(props: DatePickerProps) -> Element { document::Link { rel: "stylesheet", href: asset!("./style.css") } div { date_picker::DatePicker { - class: "date-picker", + class: "dx-date-picker", on_value_change: props.on_value_change, selected_date: props.selected_date, disabled: props.disabled, @@ -41,7 +41,7 @@ pub fn DateRangePicker(props: DateRangePickerProps) -> Element { document::Link { rel: "stylesheet", href: asset!("./style.css") } div { date_picker::DateRangePicker { - class: "date-picker", + class: "dx-date-picker", on_range_change: props.on_range_change, selected_range: props.selected_range, disabled: props.disabled, @@ -123,7 +123,7 @@ pub fn DatePickerPopoverTrigger(props: PopoverTriggerProps) -> Element { rsx! { PopoverTrigger { aria_label: "Show Calendar", attributes: props.attributes, svg { - class: "date-picker-expand-icon", + class: "dx-date-picker-expand-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", polyline { points: "6 9 12 15 18 9" } @@ -136,7 +136,7 @@ pub fn DatePickerPopoverTrigger(props: PopoverTriggerProps) -> Element { pub fn DatePickerPopoverContent(props: PopoverContentProps) -> Element { rsx! { PopoverContent { - class: "popover-content", + class: "dx-popover-content", id: props.id, side: props.side, align: props.align, diff --git a/preview/src/components/date_picker/style.css b/preview/src/components/date_picker/style.css index 4fb434c2..2ee6663f 100644 --- a/preview/src/components/date_picker/style.css +++ b/preview/src/components/date_picker/style.css @@ -1,10 +1,10 @@ -.date-picker { +.dx-date-picker { position: relative; display: inline-flex; align-items: center; } -.date-picker-group .popover-trigger { +.dx-date-picker-group .dx-popover-trigger { display: inline-flex; align-items: center; justify-content: center; @@ -15,11 +15,11 @@ transition: rotate 150ms cubic-bezier(0.4, 0, 0.2, 1); } -.popover[data-state="open"] div .date-picker-trigger { +.dx-popover[data-state="open"] div .dx-date-picker-trigger { rotate: 180deg; } -.date-picker-expand-icon { +.dx-date-picker-expand-icon { width: 20px; height: 20px; fill: none; @@ -34,7 +34,7 @@ opacity: 0.5; } -.date-picker-group { +.dx-date-picker-group { display: flex; width: fit-content; min-width: 150px; @@ -54,24 +54,24 @@ transition: background-color 100ms ease-out; } -.date-picker-group .popover-content { +.dx-date-picker-group .dx-popover-content { max-width: unset; padding: 0; } -.date-segment { +.dx-date-segment { caret-color: transparent; } -.date-segment[no-date="true"] { +.dx-date-segment[no-date="true"] { color: var(--secondary-color-5); } -.date-segment[is-separator="true"] { +.dx-date-segment[is-separator="true"] { padding: 0; } -.date-segment:focus-visible { +.dx-date-segment:focus-visible { border-radius: 0.25rem; background: var(--secondary-color-3); color: var(--primary-color); diff --git a/preview/src/components/dialog/component.rs b/preview/src/components/dialog/component.rs index 63fd6097..fbe9f758 100644 --- a/preview/src/components/dialog/component.rs +++ b/preview/src/components/dialog/component.rs @@ -8,7 +8,7 @@ pub fn DialogRoot(props: DialogRootProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } dialog::DialogRoot { - class: "dialog-backdrop", + class: "dx-dialog-backdrop", id: props.id, is_modal: props.is_modal, open: props.open, @@ -23,7 +23,7 @@ pub fn DialogRoot(props: DialogRootProps) -> Element { #[component] pub fn DialogContent(props: DialogContentProps) -> Element { rsx! { - dialog::DialogContent { class: "dialog", id: props.id, attributes: props.attributes, {props.children} } + dialog::DialogContent { class: "dx-dialog", id: props.id, attributes: props.attributes, {props.children} } } } @@ -31,7 +31,7 @@ pub fn DialogContent(props: DialogContentProps) -> Element { pub fn DialogTitle(props: DialogTitleProps) -> Element { rsx! { dialog::DialogTitle { - class: "dialog-title", + class: "dx-dialog-title", id: props.id, attributes: props.attributes, {props.children} @@ -43,7 +43,7 @@ pub fn DialogTitle(props: DialogTitleProps) -> Element { pub fn DialogDescription(props: DialogDescriptionProps) -> Element { rsx! { dialog::DialogDescription { - class: "dialog-description", + class: "dx-dialog-description", id: props.id, attributes: props.attributes, {props.children} diff --git a/preview/src/components/dialog/style.css b/preview/src/components/dialog/style.css index 89ac33e9..a6f49f25 100644 --- a/preview/src/components/dialog/style.css +++ b/preview/src/components/dialog/style.css @@ -1,5 +1,5 @@ /* Dialog Backdrop */ -.dialog-backdrop { +.dx-dialog-backdrop { position: fixed; z-index: 1000; background: rgb(0 0 0 / 30%); @@ -8,12 +8,12 @@ will-change: transform, opacity; } -.dialog-backdrop[data-state="closed"] { - animation: dialog-backdrop-animate-out 150ms ease-in forwards; +.dx-dialog-backdrop[data-state="closed"] { + animation: dx-dialog-backdrop-animate-out 150ms ease-in forwards; pointer-events: none; } -@keyframes dialog-backdrop-animate-out { +@keyframes dx-dialog-backdrop-animate-out { 0% { opacity: 1; transform: scale(1) translateY(0); @@ -25,11 +25,11 @@ } } -.dialog-backdrop[data-state="open"] { - animation: dialog-content-animate-in 150ms ease-out forwards; +.dx-dialog-backdrop[data-state="open"] { + animation: dx-dialog-content-animate-in 150ms ease-out forwards; } -@keyframes dialog-content-animate-in { +@keyframes dx-dialog-content-animate-in { 0% { opacity: 0; transform: scale(0.95) translateY(-2px); @@ -42,7 +42,7 @@ } /* Dialog Container - improved for theme consistency */ -.dialog { +.dx-dialog { position: fixed; z-index: 1001; top: 50%; @@ -66,27 +66,27 @@ transform: translate(-50%, -50%); } -.dialog-title { +.dx-dialog-title { margin: 0; color: var(--secondary-color-4); font-size: 1.25rem; font-weight: 700; } -.dialog-description { +.dx-dialog-description { margin: 0; color: var(--secondary-color-5); font-size: 1rem; } @media (width >= 40rem) { - .dialog { + .dx-dialog { max-width: 32rem; text-align: left; } } -.dialog-close { +.dx-dialog-close { position: absolute; top: 1rem; right: 1rem; @@ -101,6 +101,6 @@ line-height: 1; } -.dialog-close:hover { +.dx-dialog-close:hover { color: var(--secondary-color-1); } diff --git a/preview/src/components/dropdown_menu/component.rs b/preview/src/components/dropdown_menu/component.rs index 203a3299..ddc95eb2 100644 --- a/preview/src/components/dropdown_menu/component.rs +++ b/preview/src/components/dropdown_menu/component.rs @@ -8,7 +8,7 @@ use dioxus_primitives::merge_attributes; #[component] pub fn DropdownMenu(props: DropdownMenuProps) -> Element { - let base = attributes!(div { class: "dropdown-menu" }); + let base = attributes!(div { class: "dx-dropdown-menu" }); let merged = merge_attributes(vec![base, props.attributes.clone()]); rsx! { @@ -27,7 +27,7 @@ pub fn DropdownMenu(props: DropdownMenuProps) -> Element { #[component] pub fn DropdownMenuTrigger(props: DropdownMenuTriggerProps) -> Element { - let base = attributes!(button { class: "dropdown-menu-trigger" }); + let base = attributes!(button { class: "dx-dropdown-menu-trigger" }); let merged = merge_attributes(vec![base, props.attributes]); rsx! { @@ -37,7 +37,7 @@ pub fn DropdownMenuTrigger(props: DropdownMenuTriggerProps) -> Element { #[component] pub fn DropdownMenuContent(props: DropdownMenuContentProps) -> Element { - let base = attributes!(div { class: "dropdown-menu-content" }); + let base = attributes!(div { class: "dx-dropdown-menu-content" }); let merged = merge_attributes(vec![base, props.attributes.clone()]); rsx! { @@ -49,7 +49,7 @@ pub fn DropdownMenuContent(props: DropdownMenuContentProps) -> Element { pub fn DropdownMenuItem( props: DropdownMenuItemProps, ) -> Element { - let base = attributes!(div { class: "dropdown-menu-item" }); + let base = attributes!(div { class: "dx-dropdown-menu-item" }); let merged = merge_attributes(vec![base, props.attributes.clone()]); rsx! { diff --git a/preview/src/components/dropdown_menu/style.css b/preview/src/components/dropdown_menu/style.css index 6f2df2a3..25982804 100644 --- a/preview/src/components/dropdown_menu/style.css +++ b/preview/src/components/dropdown_menu/style.css @@ -1,10 +1,10 @@ /* Dropdown Menu Styles */ -.dropdown-menu { +.dx-dropdown-menu { position: relative; display: inline-block; } -.dropdown-menu-trigger { +.dx-dropdown-menu-trigger { padding: 8px 18px; border: none; border-radius: 0.5rem; @@ -17,16 +17,16 @@ transition: background-color 0.2s ease, color 0.2s ease; } -.dropdown-menu-trigger:hover { +.dx-dropdown-menu-trigger:hover { background-color: var(--primary-color-4); color: var(--secondary-color-1); } -.dropdown-menu-trigger:focus-visible { +.dx-dropdown-menu-trigger:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } -.dropdown-menu-content { +.dx-dropdown-menu-content { position: absolute; z-index: 1000; top: 100%; @@ -35,7 +35,7 @@ padding: 0.25rem; border-radius: 0.5rem; margin-top: 4px; - animation: slideIn 0.1s ease-out; + animation: dx-slideIn 0.1s ease-out; background-color: var(--dark, var(--primary-color-5)) var(--light, var(--primary-color)); box-shadow: inset 0 0 0 1px var(--dark, var(--primary-color-7)) @@ -47,12 +47,12 @@ transition: transform 0.2s ease, opacity 0.2s ease; } -.dropdown-menu-content[data-state="closed"] { - animation: dropdown-menu-content-animate-out 150ms ease-in forwards; +.dx-dropdown-menu-content[data-state="closed"] { + animation: dx-dropdown-menu-content-animate-out 150ms ease-in forwards; pointer-events: none; } -@keyframes dropdown-menu-content-animate-out { +@keyframes dx-dropdown-menu-content-animate-out { 0% { opacity: 1; transform: scale(1) translateY(0); @@ -64,11 +64,11 @@ } } -.dropdown-menu-content[data-state="open"] { - animation: dropdown-menu-content-animate-in 150ms ease-out forwards; +.dx-dropdown-menu-content[data-state="open"] { + animation: dx-dropdown-menu-content-animate-in 150ms ease-out forwards; } -@keyframes dropdown-menu-content-animate-in { +@keyframes dx-dropdown-menu-content-animate-in { 0% { opacity: 0; transform: scale(0.95) translateY(-2px); @@ -80,7 +80,7 @@ } } -.dropdown-menu-item { +.dx-dropdown-menu-item { display: flex; align-items: center; padding: 8px 12px; @@ -93,13 +93,13 @@ user-select: none; } -.dropdown-menu-item[data-disabled="true"] { +.dx-dropdown-menu-item[data-disabled="true"] { color: var(--secondary-color-5); cursor: not-allowed; } -.dropdown-menu-item:hover:not([data-disabled="true"]), -.dropdown-menu-item:focus-visible { +.dx-dropdown-menu-item:hover:not([data-disabled="true"]), +.dx-dropdown-menu-item:focus-visible { background: var(--dark, var(--primary-color-7)) var(--light, var(--primary-color-4)); color: var(--secondary-color-1); diff --git a/preview/src/components/dropdown_menu/variants/main/mod.rs b/preview/src/components/dropdown_menu/variants/main/mod.rs index 7cd77a1f..9d1ee540 100644 --- a/preview/src/components/dropdown_menu/variants/main/mod.rs +++ b/preview/src/components/dropdown_menu/variants/main/mod.rs @@ -19,7 +19,7 @@ pub fn Demo() -> Element { let operations = Operation::iter().enumerate().map(|(i, o)| { rsx! { DropdownMenuItem:: { - class: "dropdown-menu-item", + class: "dx-dropdown-menu-item", value: o, index: i, disabled: matches!(o, Operation::Undo), @@ -32,9 +32,9 @@ pub fn Demo() -> Element { }); rsx! { - DropdownMenu { class: "dropdown-menu", default_open: false, - DropdownMenuTrigger { class: "dropdown-menu-trigger", "Open Menu" } - DropdownMenuContent { class: "dropdown-menu-content", {operations} } + DropdownMenu { class: "dx-dropdown-menu", default_open: false, + DropdownMenuTrigger { class: "dx-dropdown-menu-trigger", "Open Menu" } + DropdownMenuContent { class: "dx-dropdown-menu-content", {operations} } } if let Some(op) = selected_operation() { "Selected: {op}" diff --git a/preview/src/components/form/style.css b/preview/src/components/form/style.css index 15d816c2..6fae01cb 100644 --- a/preview/src/components/form/style.css +++ b/preview/src/components/form/style.css @@ -10,7 +10,7 @@ font-size: 14px; } -.form-example button { +.dx-form-example button { padding: 8px 16px; border: 1px solid var(--primary-color-6); border-radius: 4px; diff --git a/preview/src/components/hover_card/component.rs b/preview/src/components/hover_card/component.rs index 9ba2e775..b0739daf 100644 --- a/preview/src/components/hover_card/component.rs +++ b/preview/src/components/hover_card/component.rs @@ -8,7 +8,7 @@ pub fn HoverCard(props: HoverCardProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } hover_card::HoverCard { - class: "hover-card", + class: "dx-hover-card", open: props.open, default_open: props.default_open, on_open_change: props.on_open_change, @@ -23,7 +23,7 @@ pub fn HoverCard(props: HoverCardProps) -> Element { pub fn HoverCardTrigger(props: HoverCardTriggerProps) -> Element { rsx! { hover_card::HoverCardTrigger { - class: "hover-card-trigger", + class: "dx-hover-card-trigger", id: props.id, attributes: props.attributes, {props.children} @@ -35,7 +35,7 @@ pub fn HoverCardTrigger(props: HoverCardTriggerProps) -> Element { pub fn HoverCardContent(props: HoverCardContentProps) -> Element { rsx! { hover_card::HoverCardContent { - class: "hover-card-content", + class: "dx-hover-card-content", side: props.side, align: props.align, id: props.id, diff --git a/preview/src/components/hover_card/style.css b/preview/src/components/hover_card/style.css index 3d95afb4..9d9b2154 100644 --- a/preview/src/components/hover_card/style.css +++ b/preview/src/components/hover_card/style.css @@ -1,14 +1,14 @@ /* Hover Card Styles */ -.hover-card { +.dx-hover-card { position: relative; display: inline-block; } -.hover-card-trigger { +.dx-hover-card-trigger { display: inline-block; } -.hover-card-content { +.dx-hover-card-content { position: absolute; z-index: 1000; min-width: 200px; @@ -16,7 +16,7 @@ border: 1px solid var(--light, var(--primary-color-6)) var(--dark, var(--primary-color-7)); border-radius: 0.5rem; - animation: hover-card-fade-in 0.1s ease-out; + animation: dx-hover-card-fade-in 0.1s ease-out; background: var(--light, var(--primary-color)) var(--dark, var(--primary-color-5)); @@ -25,7 +25,7 @@ } /* Positioning based on side */ -.hover-card-content[data-side="top"] { +.dx-hover-card-content[data-side="top"] { position: absolute; bottom: 100%; left: 50%; @@ -33,7 +33,7 @@ transform: translateX(-50%); } -.hover-card-content[data-side="right"] { +.dx-hover-card-content[data-side="right"] { position: absolute; top: 50%; left: 100%; @@ -41,7 +41,7 @@ transform: translateY(-50%); } -.hover-card-content[data-side="bottom"] { +.dx-hover-card-content[data-side="bottom"] { position: absolute; top: 100%; left: 50%; @@ -49,7 +49,7 @@ transform: translateX(-50%); } -.hover-card-content[data-side="left"] { +.dx-hover-card-content[data-side="left"] { position: absolute; top: 50%; right: 100%; @@ -58,47 +58,47 @@ } /* Alignment styles for top and bottom */ -.hover-card-content[data-side="top"][data-align="start"], -.hover-card-content[data-side="bottom"][data-align="start"] { +.dx-hover-card-content[data-side="top"][data-align="start"], +.dx-hover-card-content[data-side="bottom"][data-align="start"] { left: 0; transform: none; } -.hover-card-content[data-side="top"][data-align="center"], -.hover-card-content[data-side="bottom"][data-align="center"] { +.dx-hover-card-content[data-side="top"][data-align="center"], +.dx-hover-card-content[data-side="bottom"][data-align="center"] { left: 50%; transform: translateX(-50%); } -.hover-card-content[data-side="top"][data-align="end"], -.hover-card-content[data-side="bottom"][data-align="end"] { +.dx-hover-card-content[data-side="top"][data-align="end"], +.dx-hover-card-content[data-side="bottom"][data-align="end"] { right: 0; left: auto; transform: none; } /* Alignment styles for left and right */ -.hover-card-content[data-side="left"][data-align="start"], -.hover-card-content[data-side="right"][data-align="start"] { +.dx-hover-card-content[data-side="left"][data-align="start"], +.dx-hover-card-content[data-side="right"][data-align="start"] { top: 0; transform: none; } -.hover-card-content[data-side="left"][data-align="center"], -.hover-card-content[data-side="right"][data-align="center"] { +.dx-hover-card-content[data-side="left"][data-align="center"], +.dx-hover-card-content[data-side="right"][data-align="center"] { top: 50%; transform: translateY(-50%); } -.hover-card-content[data-side="left"][data-align="end"], -.hover-card-content[data-side="right"][data-align="end"] { +.dx-hover-card-content[data-side="left"][data-align="end"], +.dx-hover-card-content[data-side="right"][data-align="end"] { top: auto; bottom: 0; transform: none; } /* Animation */ -@keyframes hover-card-fade-in { +@keyframes dx-hover-card-fade-in { from { opacity: 0; } @@ -109,10 +109,10 @@ } /* State styles */ -.hover-card[data-disabled="true"] .hover-card-trigger { +.dx-hover-card[data-disabled="true"] .dx-hover-card-trigger { color: var(--secondary-color-5); } -.hover-card-content[data-state="closed"] { +.dx-hover-card-content[data-state="closed"] { display: none; } diff --git a/preview/src/components/input/component.rs b/preview/src/components/input/component.rs index 5a1807ed..bc84c513 100644 --- a/preview/src/components/input/component.rs +++ b/preview/src/components/input/component.rs @@ -28,7 +28,7 @@ pub fn Input( rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } input { - class: "input", + class: "dx-input", oninput: move |e| _ = oninput.map(|callback| callback(e)), onchange: move |e| _ = onchange.map(|callback| callback(e)), oninvalid: move |e| _ = oninvalid.map(|callback| callback(e)), diff --git a/preview/src/components/input/style.css b/preview/src/components/input/style.css index 9faf0c95..3fc2fd90 100644 --- a/preview/src/components/input/style.css +++ b/preview/src/components/input/style.css @@ -1,5 +1,5 @@ /* Input Styles */ -.input { +.dx-input { position: relative; display: flex; box-sizing: border-box; @@ -21,17 +21,17 @@ transition: background-color 100ms ease-out; } -.input::placeholder { +.dx-input::placeholder { color: var(--secondary-color-5); } -.input:disabled { +.dx-input:disabled { color: var(--secondary-color-5); cursor: not-allowed; } -.input:hover:not(:disabled), -.input:focus-visible { +.dx-input:hover:not(:disabled), +.dx-input:focus-visible { background: var(--light, var(--primary-color-4)) var(--dark, color-mix(in oklab, #FFFFFF26 50%, transparent)); color: var(--secondary-color-1); diff --git a/preview/src/components/label/component.rs b/preview/src/components/label/component.rs index 3874e5be..52c9f583 100644 --- a/preview/src/components/label/component.rs +++ b/preview/src/components/label/component.rs @@ -6,7 +6,7 @@ pub fn Label(props: LabelProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } label::Label { - class: "label", + class: "dx-label", html_for: props.html_for, attributes: props.attributes, {props.children} diff --git a/preview/src/components/label/style.css b/preview/src/components/label/style.css index 3cc7f3a6..190a3748 100644 --- a/preview/src/components/label/style.css +++ b/preview/src/components/label/style.css @@ -1,5 +1,5 @@ /* Label Styles */ -.label { +.dx-label { display: flex; align-items: center; color: var(--secondary-color-4); diff --git a/preview/src/components/menubar/component.rs b/preview/src/components/menubar/component.rs index abc18374..cb2eeb9c 100644 --- a/preview/src/components/menubar/component.rs +++ b/preview/src/components/menubar/component.rs @@ -9,7 +9,7 @@ pub fn Menubar(props: MenubarProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } menubar::Menubar { - class: "menubar", + class: "dx-menubar", disabled: props.disabled, roving_loop: props.roving_loop, attributes: props.attributes, @@ -22,7 +22,7 @@ pub fn Menubar(props: MenubarProps) -> Element { pub fn MenubarMenu(props: MenubarMenuProps) -> Element { rsx! { menubar::MenubarMenu { - class: "menubar-menu", + class: "dx-menubar-menu", index: props.index, disabled: props.disabled, attributes: props.attributes, @@ -34,7 +34,7 @@ pub fn MenubarMenu(props: MenubarMenuProps) -> Element { #[component] pub fn MenubarTrigger(props: MenubarTriggerProps) -> Element { rsx! { - menubar::MenubarTrigger { class: "menubar-trigger", attributes: props.attributes, {props.children} } + menubar::MenubarTrigger { class: "dx-menubar-trigger", attributes: props.attributes, {props.children} } } } @@ -42,7 +42,7 @@ pub fn MenubarTrigger(props: MenubarTriggerProps) -> Element { pub fn MenubarContent(props: MenubarContentProps) -> Element { rsx! { menubar::MenubarContent { - class: "menubar-content", + class: "dx-menubar-content", id: props.id, attributes: props.attributes, {props.children} @@ -54,7 +54,7 @@ pub fn MenubarContent(props: MenubarContentProps) -> Element { pub fn MenubarItem(props: MenubarItemProps) -> Element { rsx! { menubar::MenubarItem { - class: "menubar-item", + class: "dx-menubar-item", index: props.index, value: props.value, disabled: props.disabled, diff --git a/preview/src/components/menubar/style.css b/preview/src/components/menubar/style.css index 3653738a..5dc664b0 100644 --- a/preview/src/components/menubar/style.css +++ b/preview/src/components/menubar/style.css @@ -1,4 +1,4 @@ -.menubar { +.dx-menubar { display: flex; box-sizing: border-box; padding: 0.25rem; @@ -9,11 +9,11 @@ gap: 0.25rem; } -.menubar-menu { +.dx-menubar-menu { position: relative; } -.menubar-trigger { +.dx-menubar-trigger { padding: 8px 12px; border: none; border-radius: calc(0.5rem - 0.25rem); @@ -23,26 +23,26 @@ transition: background-color 100ms ease-out; } -.menubar-menu[data-state="open"] .menubar-trigger { +.dx-menubar-menu[data-state="open"] .dx-menubar-trigger { background-color: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-7)); color: var(--secondary-color-1); } -.menubar-trigger[data-disabled="true"] { +.dx-menubar-trigger[data-disabled="true"] { color: var(--secondary-color-5); cursor: not-allowed; } -.menubar-trigger:hover:not([data-disabled="true"]), -.menubar-trigger:focus-visible { +.dx-menubar-trigger:hover:not([data-disabled="true"]), +.dx-menubar-trigger:focus-visible { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-7)); color: var(--secondary-color-1); outline: none; } -.menubar-content { +.dx-menubar-content { position: absolute; z-index: 1000; top: 100%; @@ -61,16 +61,16 @@ will-change: transform, opacity; } -.menubar-menu:first-child .menubar-content { +.dx-menubar-menu:first-child .dx-menubar-content { margin-left: -0.25rem; } -.menubar-content[data-state="closed"] { - animation: menubar-content-animate-out 150ms ease-in forwards; +.dx-menubar-content[data-state="closed"] { + animation: dx-menubar-content-animate-out 150ms ease-in forwards; pointer-events: none; } -@keyframes menubar-content-animate-out { +@keyframes dx-menubar-content-animate-out { 0% { opacity: 1; transform: scale(1) translateY(0); @@ -82,12 +82,12 @@ } } -.menubar-content[data-state="open"] { - animation: menubar-content-animate-in 150ms ease-out forwards; +.dx-menubar-content[data-state="open"] { + animation: dx-menubar-content-animate-in 150ms ease-out forwards; pointer-events: auto; } -@keyframes menubar-content-animate-in { +@keyframes dx-menubar-content-animate-in { 0% { opacity: 0; transform: scale(0.95) translateY(-2px); @@ -99,7 +99,7 @@ } } -.menubar-item { +.dx-menubar-item { display: block; padding: 8px 12px; border-radius: calc(0.5rem - 0.25rem); @@ -107,13 +107,13 @@ font-size: 14px; } -.menubar-item[data-disabled="true"] { +.dx-menubar-item[data-disabled="true"] { color: var(--secondary-color-5); cursor: not-allowed; } -.menubar-item:hover:not([data-disabled="true"]), -.menubar-item:focus-visible { +.dx-menubar-item:hover:not([data-disabled="true"]), +.dx-menubar-item:focus-visible { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-7)); color: var(--secondary-color-1); diff --git a/preview/src/components/navbar/component.rs b/preview/src/components/navbar/component.rs index 92584b39..b5e14db2 100644 --- a/preview/src/components/navbar/component.rs +++ b/preview/src/components/navbar/component.rs @@ -8,7 +8,7 @@ pub fn Navbar(props: NavbarProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } navbar::Navbar { - class: "navbar", + class: "dx-navbar", disabled: props.disabled, roving_loop: props.roving_loop, attributes: props.attributes, @@ -21,7 +21,7 @@ pub fn Navbar(props: NavbarProps) -> Element { pub fn NavbarNav(props: NavbarNavProps) -> Element { rsx! { navbar::NavbarNav { - class: "navbar-nav", + class: "dx-navbar-nav", index: props.index, disabled: props.disabled, attributes: props.attributes, @@ -33,10 +33,10 @@ pub fn NavbarNav(props: NavbarNavProps) -> Element { #[component] pub fn NavbarTrigger(props: NavbarTriggerProps) -> Element { rsx! { - navbar::NavbarTrigger { class: "navbar-trigger", attributes: props.attributes, + navbar::NavbarTrigger { class: "dx-navbar-trigger", attributes: props.attributes, {props.children} svg { - class: "navbar-expand-icon", + class: "dx-navbar-expand-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", polyline { points: "6 9 12 15 18 9" } @@ -49,7 +49,7 @@ pub fn NavbarTrigger(props: NavbarTriggerProps) -> Element { pub fn NavbarContent(props: NavbarContentProps) -> Element { rsx! { navbar::NavbarContent { - class: "navbar-content", + class: "dx-navbar-content", id: props.id, attributes: props.attributes, {props.children} @@ -61,7 +61,7 @@ pub fn NavbarContent(props: NavbarContentProps) -> Element { pub fn NavbarItem(props: NavbarItemProps) -> Element { rsx! { navbar::NavbarItem { - class: "navbar-item", + class: "dx-navbar-item", index: props.index, value: props.value, disabled: props.disabled, diff --git a/preview/src/components/navbar/style.css b/preview/src/components/navbar/style.css index 151cc94e..d44c56eb 100644 --- a/preview/src/components/navbar/style.css +++ b/preview/src/components/navbar/style.css @@ -1,4 +1,4 @@ -.navbar { +.dx-navbar { display: flex; box-sizing: border-box; padding: 0.25rem; @@ -7,11 +7,11 @@ gap: 0.25rem; } -.navbar-nav { +.dx-navbar-nav { position: relative; } -.navbar-trigger { +.dx-navbar-trigger { display: flex; flex-direction: row; align-items: center; @@ -25,19 +25,19 @@ transition: background-color 100ms ease-out; } -.navbar-nav[data-state="open"] .navbar-trigger { +.dx-navbar-nav[data-state="open"] .dx-navbar-trigger { background-color: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-7)); color: var(--secondary-color-1); } -.navbar-trigger[data-disabled="true"] { +.dx-navbar-trigger[data-disabled="true"] { color: var(--secondary-color-5); cursor: not-allowed; } -.navbar-trigger:hover:not([data-disabled="true"]), -.navbar-trigger:focus-visible { +.dx-navbar-trigger:hover:not([data-disabled="true"]), +.dx-navbar-trigger:focus-visible { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-7)); color: var(--secondary-color-1); @@ -45,7 +45,7 @@ } /* Include the top margin in the navbar content pointer events */ -.navbar-content::before { +.dx-navbar-content::before { position: absolute; top: -0.5rem; left: 0; @@ -54,7 +54,7 @@ content: ""; } -.navbar-content { +.dx-navbar-content { position: absolute; z-index: 1000; top: 100%; @@ -73,27 +73,27 @@ will-change: transform, opacity; } -.navbar-nav:first-child .navbar-content { +.dx-navbar-nav:first-child .dx-navbar-content { margin-left: -0.25rem; } -.navbar-content[data-state="closed"] { +.dx-navbar-content[data-state="closed"] { transition: opacity 150ms ease-in, transform 150ms ease-in; } -.navbar-content[data-state="closed"][data-open-menu-direction="start"] { +.dx-navbar-content[data-state="closed"][data-open-menu-direction="start"] { transform: translateX(-100%) scale(0.98); } -.navbar-content[data-state="closed"][data-open-menu-direction="end"] { +.dx-navbar-content[data-state="closed"][data-open-menu-direction="end"] { transform: translateX(100%) scale(0.98); } -.navbar-content[data-state="closed"][data-open-menu-direction="closed"] { +.dx-navbar-content[data-state="closed"][data-open-menu-direction="closed"] { transform: translateY(1rem) scale(0.98); } -.navbar-content[data-state="open"] { +.dx-navbar-content[data-state="open"] { opacity: 1; pointer-events: auto; transform: translateX(0) translateY(0) scale(1); @@ -101,7 +101,7 @@ transform 200ms cubic-bezier(0.16, 1, 0.3, 1); } -.navbar-item { +.dx-navbar-item { display: block; padding: 8px 12px; border-radius: calc(0.5rem - 0.25rem); @@ -111,13 +111,13 @@ text-decoration: none; } -.navbar-item[data-disabled="true"] { +.dx-navbar-item[data-disabled="true"] { color: var(--secondary-color-5); cursor: not-allowed; } -.navbar-item:hover:not([data-disabled="true"]), -.navbar-item:focus-visible { +.dx-navbar-item:hover:not([data-disabled="true"]), +.dx-navbar-item:focus-visible { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-7)); color: var(--secondary-color-1); @@ -129,7 +129,7 @@ opacity: 0.5; } -.navbar-expand-icon { +.dx-navbar-expand-icon { width: 20px; height: 20px; fill: none; @@ -140,6 +140,6 @@ transition: rotate 150ms cubic-bezier(0.4, 0, 0.2, 1); } -.navbar-nav[data-state="open"] .navbar-expand-icon { +.dx-navbar-nav[data-state="open"] .dx-navbar-expand-icon { rotate: 180deg; } diff --git a/preview/src/components/pagination/component.rs b/preview/src/components/pagination/component.rs index f04eff42..1e472d30 100644 --- a/preview/src/components/pagination/component.rs +++ b/preview/src/components/pagination/component.rs @@ -41,7 +41,7 @@ pub fn Pagination( rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } nav { - class: "pagination", + class: "dx-pagination", "data-slot": "pagination", role: "navigation", aria_label: "pagination", @@ -58,7 +58,7 @@ pub fn PaginationContent( ) -> Element { rsx! { ul { - class: "pagination-content", + class: "dx-pagination-content", "data-slot": "pagination-content", ..attributes, {children} @@ -73,7 +73,7 @@ pub fn PaginationItem( ) -> Element { rsx! { li { - class: "pagination-item", + class: "dx-pagination-item", "data-slot": "pagination-item", ..attributes, {children} @@ -104,7 +104,7 @@ pub fn PaginationLink(props: PaginationLinkProps) -> Element { let data_kind = props.data_kind.map(|kind| kind.attr()); rsx! { a { - class: "pagination-link", + class: "dx-pagination-link", "data-slot": "pagination-link", "data-active": props.is_active, "data-size": props.size.class(), @@ -151,12 +151,12 @@ pub fn PaginationPrevious( attributes, // ChevronLeft icon from lucide https://lucide.dev/icons/chevron-left svg { - class: "pagination-icon", + class: "dx-pagination-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", polyline { points: "15 6 9 12 15 18" } } - span { class: "pagination-label", "Previous" } + span { class: "dx-pagination-label", "Previous" } } } } @@ -179,10 +179,10 @@ pub fn PaginationNext( onmousedown, onmouseup, attributes, - span { class: "pagination-label", "Next" } + span { class: "dx-pagination-label", "Next" } // ChevronRight icon from lucide https://lucide.dev/icons/chevron-right svg { - class: "pagination-icon", + class: "dx-pagination-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", polyline { points: "9 6 15 12 9 18" } @@ -197,20 +197,20 @@ pub fn PaginationEllipsis( ) -> Element { rsx! { span { - class: "pagination-ellipsis", + class: "dx-pagination-ellipsis", "data-slot": "pagination-ellipsis", aria_hidden: "true", ..attributes, // MoreHorizontal icon from lucide https://lucide.dev/icons/more-horizontal svg { - class: "pagination-icon", + class: "dx-pagination-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", circle { cx: "5", cy: "12", r: "1.5" } circle { cx: "12", cy: "12", r: "1.5" } circle { cx: "19", cy: "12", r: "1.5" } } - span { class: "sr-only", "More pages" } + span { class: "dx-sr-only", "More pages" } } } } diff --git a/preview/src/components/pagination/style.css b/preview/src/components/pagination/style.css index ae0cf434..80e22cdf 100644 --- a/preview/src/components/pagination/style.css +++ b/preview/src/components/pagination/style.css @@ -1,11 +1,11 @@ -.pagination { +.dx-pagination { display: flex; width: 100%; justify-content: center; margin: 0 auto; } -.pagination-content { +.dx-pagination-content { display: flex; align-items: center; padding: 0; @@ -14,7 +14,7 @@ list-style: none; } -.pagination-link { +.dx-pagination-link { display: inline-flex; box-sizing: border-box; align-items: center; @@ -29,71 +29,71 @@ transition: background-color 0.2s ease, color 0.2s ease; } -.pagination-link:focus-visible { +.dx-pagination-link:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } -.pagination-link[data-size="icon"] { +.dx-pagination-link[data-size="icon"] { width: 2rem; height: 2rem; padding: 0; } -.pagination-ellipsis { +.dx-pagination-ellipsis { display: flex; align-items: center; justify-content: center; color: var(--secondary-color-4); } -.pagination-ellipsis .pagination-icon { +.dx-pagination-ellipsis .dx-pagination-icon { fill: currentcolor; } -.pagination-link[data-size="icon"], -.pagination-ellipsis { +.dx-pagination-link[data-size="icon"], +.dx-pagination-ellipsis { width: 2rem; height: 2rem; } -.pagination-link[data-size="default"] { +.dx-pagination-link[data-size="default"] { height: 2rem; padding: 0.5rem 1rem; } -.pagination-link[data-active="true"] { +.dx-pagination-link[data-active="true"] { border: 1px solid var(--primary-color-6); background-color: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3)); } -.pagination-link[data-active="true"]:hover { +.dx-pagination-link[data-active="true"]:hover { background-color: var(--primary-color-4); } -.pagination-link[data-active="false"]:hover { +.dx-pagination-link[data-active="false"]:hover { background-color: var(--primary-color-5); color: var(--secondary-color-1); } -.pagination-link[data-kind="previous"], -.pagination-link[data-kind="next"] { +.dx-pagination-link[data-kind="previous"], +.dx-pagination-link[data-kind="next"] { padding-right: 0.625rem; padding-left: 0.625rem; gap: 0.25rem; } -.pagination-label { +.dx-pagination-label { display: none; } @media (width >= 640px) { - .pagination-label { + .dx-pagination-label { display: inline; } } -.pagination-icon { +.dx-pagination-icon { width: 1rem; height: 1rem; fill: none; @@ -106,7 +106,7 @@ /* TODO: move to shared css */ /* Screen-reader only text */ -.sr-only { +.dx-sr-only { position: absolute; overflow: hidden; width: 1px; diff --git a/preview/src/components/popover/component.rs b/preview/src/components/popover/component.rs index 34f7bdb1..167e9186 100644 --- a/preview/src/components/popover/component.rs +++ b/preview/src/components/popover/component.rs @@ -8,7 +8,7 @@ pub fn PopoverRoot(props: PopoverRootProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } popover::PopoverRoot { - class: "popover", + class: "dx-popover", is_modal: props.is_modal, open: props.open, default_open: props.default_open, @@ -22,7 +22,7 @@ pub fn PopoverRoot(props: PopoverRootProps) -> Element { #[component] pub fn PopoverTrigger(props: PopoverTriggerProps) -> Element { rsx! { - popover::PopoverTrigger { class: "popover-trigger", attributes: props.attributes, {props.children} } + popover::PopoverTrigger { class: "dx-popover-trigger", attributes: props.attributes, {props.children} } } } @@ -30,7 +30,7 @@ pub fn PopoverTrigger(props: PopoverTriggerProps) -> Element { pub fn PopoverContent(props: PopoverContentProps) -> Element { rsx! { popover::PopoverContent { - class: "popover-content", + class: "dx-popover-content", id: props.id, side: props.side, align: props.align, diff --git a/preview/src/components/popover/style.css b/preview/src/components/popover/style.css index 299dfaf2..b006458f 100644 --- a/preview/src/components/popover/style.css +++ b/preview/src/components/popover/style.css @@ -1,9 +1,9 @@ -.popover { +.dx-popover { position: relative; display: inline-block; } -.popover-content { +.dx-popover-content { position: fixed; z-index: 1000; display: flex; @@ -14,7 +14,7 @@ padding: .25rem; border-radius: .5rem; margin-top: .5rem; - background: var(--light, var(--primary-color)) + background: var(--light, var(--primary-color)) var(--dark, var(--primary-color-5)); box-shadow: inset 0 0 0 1px var(--light, var(--primary-color-6)) var(--dark, var(--primary-color-7)); text-align: center; @@ -23,16 +23,16 @@ will-change: transform, opacity; } -.popover-content[data-state="closed"] { +.dx-popover-content[data-state="closed"] { display: none; } -.popover-content[data-state="open"] { +.dx-popover-content[data-state="open"] { display: flex; - animation: popover-fade-in .2s ease-in-out; + animation: dx-popover-fade-in .2s ease-in-out; } -@keyframes popover-fade-in { +@keyframes dx-popover-fade-in { from { opacity: 0; } @@ -43,7 +43,7 @@ } /* Positioning based on side */ -.popover-content[data-side="top"] { +.dx-popover-content[data-side="top"] { position: absolute; bottom: 100%; left: 50%; @@ -51,14 +51,14 @@ transform: translateX(-50%); } -.popover-content[data-side="top"]::after { +.dx-popover-content[data-side="top"]::after { top: calc(100% - 0.25rem); left: 50%; border-color: var(--secondary-color-4); border-radius: 0 0 0.1rem; } -.popover-content[data-side="right"] { +.dx-popover-content[data-side="right"] { position: absolute; top: 50%; left: 100%; @@ -66,14 +66,14 @@ transform: translateY(-50%); } -.popover-content[data-side="right"]::after { +.dx-popover-content[data-side="right"]::after { top: calc(50% - 0.25rem); left: 0; border-color: var(--secondary-color-4); border-radius: 0 0 0 0.1rem; } -.popover-content[data-side="bottom"] { +.dx-popover-content[data-side="bottom"] { position: absolute; top: 100%; left: 50%; @@ -81,14 +81,14 @@ transform: translateX(-50%); } -.popover-content[data-side="bottom"]::after { +.dx-popover-content[data-side="bottom"]::after { bottom: calc(100% - 0.25rem); left: 50%; border-color: var(--secondary-color-4); border-radius: 0.1rem 0 0; } -.popover-content[data-side="left"] { +.dx-popover-content[data-side="left"] { position: absolute; top: 50%; right: 100%; @@ -96,7 +96,7 @@ transform: translateY(-50%); } -.popover-content[data-side="left"]::after { +.dx-popover-content[data-side="left"]::after { top: calc(50% - 0.25rem); right: -0.25rem; border-color: var(--secondary-color-4); @@ -104,71 +104,71 @@ } /* Alignment styles for top and bottom */ -.popover-content[data-side="top"][data-align="start"], -.popover-content[data-side="bottom"][data-align="start"] { +.dx-popover-content[data-side="top"][data-align="start"], +.dx-popover-content[data-side="bottom"][data-align="start"] { left: 0; transform: none; } -.popover-content[data-side="top"][data-align="end"], -.popover-content[data-side="bottom"][data-align="end"] { +.dx-popover-content[data-side="top"][data-align="end"], +.dx-popover-content[data-side="bottom"][data-align="end"] { right: 0; left: auto; transform: none; } /* Alignment styles for left and right */ -.popover-content[data-side="left"][data-align="start"], -.popover-content[data-side="right"][data-align="start"] { +.dx-popover-content[data-side="left"][data-align="start"], +.dx-popover-content[data-side="right"][data-align="start"] { top: 0; transform: none; } -.popover-content[data-side="left"][data-align="center"], -.popover-content[data-side="right"][data-align="center"] { +.dx-popover-content[data-side="left"][data-align="center"], +.dx-popover-content[data-side="right"][data-align="center"] { top: 50%; transform: translateY(-50%); } -.popover-content[data-side="left"][data-align="end"], -.popover-content[data-side="right"][data-align="end"] { +.dx-popover-content[data-side="left"][data-align="end"], +.dx-popover-content[data-side="right"][data-align="end"] { top: auto; bottom: 0; transform: none; } -.popover-content-title { +.dx-popover-content-title { margin: 0; color: var(--secondary-color-4); font-size: 1.25rem; font-weight: 700; } -.popover-content-description { +.dx-popover-content-description { margin: 0; color: var(--secondary-color-5); font-size: 1rem; } -.popover-content-actions { +.dx-popover-content-actions { display: flex; flex-direction: column-reverse; gap: 12px; } @media (width >= 40rem) { - .popover-content-actions { + .dx-popover-content-actions { flex-direction: row; justify-content: flex-end; } - .popover-content { + .dx-popover-content { max-width: 32rem; text-align: left; } } -.popover-content-cancel { +.dx-popover-content-cancel { padding: 8px 18px; border: 1px solid var(--primary-color-6); border-radius: 0.5rem; @@ -180,15 +180,15 @@ transition: background-color 0.2s ease; } -.popover-content-cancel:hover { +.dx-popover-content-cancel:hover { background-color: var(--primary-color-4); } -.popover-content-cancel:focus-visible { +.dx-popover-content-cancel:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } -.popover-content-action { +.dx-popover-content-action { padding: 8px 18px; border: 1px solid var(--primary-error-color); border-radius: 0.5rem; @@ -199,15 +199,15 @@ transition: background-color 0.2s ease; } -.popover-content-action:hover { +.dx-popover-content-action:hover { background-color: var(--secondary-error-color); } -.popover-content-action:focus-visible { +.dx-popover-content-action:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } -.popover-trigger { +.dx-popover-trigger { padding: 8px 18px; border: 1px solid var(--primary-color-6); border-radius: 0.5rem; @@ -219,10 +219,10 @@ transition: background-color 0.2s ease; } -.popover-trigger:hover { +.dx-popover-trigger:hover { background-color: var(--primary-color-4); } -.popover-trigger:focus-visible { +.dx-popover-trigger:focus-visible { box-shadow: 0 0 0 2px var(--focused-border-color); } diff --git a/preview/src/components/progress/component.rs b/preview/src/components/progress/component.rs index 7bc588a9..09d88647 100644 --- a/preview/src/components/progress/component.rs +++ b/preview/src/components/progress/component.rs @@ -6,7 +6,7 @@ pub fn Progress(props: ProgressProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } progress::Progress { - class: "progress", + class: "dx-progress", value: props.value, max: props.max, attributes: props.attributes, @@ -18,6 +18,6 @@ pub fn Progress(props: ProgressProps) -> Element { #[component] pub fn ProgressIndicator(props: ProgressIndicatorProps) -> Element { rsx! { - progress::ProgressIndicator { class: "progress-indicator", attributes: props.attributes, {props.children} } + progress::ProgressIndicator { class: "dx-progress-indicator", attributes: props.attributes, {props.children} } } } diff --git a/preview/src/components/progress/style.css b/preview/src/components/progress/style.css index 43b9870b..d2726083 100644 --- a/preview/src/components/progress/style.css +++ b/preview/src/components/progress/style.css @@ -1,4 +1,4 @@ -.progress { +.dx-progress { position: relative; overflow: hidden; width: 200px; @@ -8,19 +8,19 @@ background: var(--primary-color-5); } -.progress[data-state='indeterminate'] .progress-indicator { +.dx-progress[data-state='indeterminate'] .dx-progress-indicator { width: 50%; - animation: indeterminate 1s infinite linear; + animation: dx-indeterminate 1s infinite linear; } -.progress-indicator { +.dx-progress-indicator { width: var(--progress-value, 0%); height: 100%; background-color: var(--secondary-color-1); transition: width 250ms ease; } -@keyframes indeterminate { +@keyframes dx-indeterminate { 0% { transform: translateX(-100%); } diff --git a/preview/src/components/radio_group/component.rs b/preview/src/components/radio_group/component.rs index 0607ca5e..b0041e75 100644 --- a/preview/src/components/radio_group/component.rs +++ b/preview/src/components/radio_group/component.rs @@ -6,7 +6,7 @@ pub fn RadioGroup(props: RadioGroupProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } radio_group::RadioGroup { - class: "radio-group", + class: "dx-radio-group", value: props.value, default_value: props.default_value, on_value_change: props.on_value_change, @@ -25,7 +25,7 @@ pub fn RadioGroup(props: RadioGroupProps) -> Element { pub fn RadioItem(props: RadioItemProps) -> Element { rsx! { radio_group::RadioItem { - class: "radio-item", + class: "dx-radio-item", value: props.value, index: props.index, disabled: props.disabled, diff --git a/preview/src/components/radio_group/style.css b/preview/src/components/radio_group/style.css index e144ed71..af54afcc 100644 --- a/preview/src/components/radio_group/style.css +++ b/preview/src/components/radio_group/style.css @@ -1,10 +1,10 @@ -.radio-group { +.dx-radio-group { display: flex; flex-direction: column; gap: .75rem; } -.radio-item { +.dx-radio-item { display: flex; flex-direction: row; align-items: center; @@ -22,7 +22,7 @@ box-sizing: border-box; border-radius: 1.5rem; background: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3)); - box-shadow: 0 0 0 1px var(--light, var(--primary-color-6)) + box-shadow: 0 0 0 1px var(--light, var(--primary-color-6)) var(--dark, var(--primary-color-7)); content: ""; cursor: pointer; diff --git a/preview/src/components/scroll_area/style.css b/preview/src/components/scroll_area/style.css index 8f17a355..3de6743b 100644 --- a/preview/src/components/scroll_area/style.css +++ b/preview/src/components/scroll_area/style.css @@ -1 +1 @@ -/* Scroll area doesn't require any additional styles */ \ No newline at end of file +/* Scroll area doesn't require any additional styles */ diff --git a/preview/src/components/select/component.rs b/preview/src/components/select/component.rs index 88e70f02..13ed56a9 100644 --- a/preview/src/components/select/component.rs +++ b/preview/src/components/select/component.rs @@ -9,7 +9,7 @@ pub fn Select(props: SelectProps) -> Element rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } select::Select { - class: "select", + class: "dx-select", value: props.value, default_value: props.default_value, on_value_change: props.on_value_change, @@ -27,10 +27,10 @@ pub fn Select(props: SelectProps) -> Element #[component] pub fn SelectTrigger(props: SelectTriggerProps) -> Element { rsx! { - select::SelectTrigger { class: "select-trigger", attributes: props.attributes, + select::SelectTrigger { class: "dx-select-trigger", attributes: props.attributes, {props.children} svg { - class: "select-expand-icon", + class: "dx-select-expand-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", polyline { points: "6 9 12 15 18 9" } @@ -50,7 +50,7 @@ pub fn SelectValue(props: SelectValueProps) -> Element { pub fn SelectList(props: SelectListProps) -> Element { rsx! { select::SelectList { - class: "select-list", + class: "dx-select-list", id: props.id, attributes: props.attributes, {props.children} @@ -62,7 +62,7 @@ pub fn SelectList(props: SelectListProps) -> Element { pub fn SelectGroup(props: SelectGroupProps) -> Element { rsx! { select::SelectGroup { - class: "select-group", + class: "dx-select-group", disabled: props.disabled, id: props.id, attributes: props.attributes, @@ -75,7 +75,7 @@ pub fn SelectGroup(props: SelectGroupProps) -> Element { pub fn SelectGroupLabel(props: SelectGroupLabelProps) -> Element { rsx! { select::SelectGroupLabel { - class: "select-group-label", + class: "dx-select-group-label", id: props.id, attributes: props.attributes, {props.children} @@ -87,7 +87,7 @@ pub fn SelectGroupLabel(props: SelectGroupLabelProps) -> Element { pub fn SelectOption(props: SelectOptionProps) -> Element { rsx! { select::SelectOption:: { - class: "select-option", + class: "dx-select-option", value: props.value, text_value: props.text_value, disabled: props.disabled, @@ -106,7 +106,7 @@ pub fn SelectItemIndicator() -> Element { rsx! { select::SelectItemIndicator { svg { - class: "select-check-icon", + class: "dx-select-check-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", path { d: "M5 13l4 4L19 7" } diff --git a/preview/src/components/select/style.css b/preview/src/components/select/style.css index 5a98dd3e..30393e5a 100644 --- a/preview/src/components/select/style.css +++ b/preview/src/components/select/style.css @@ -1,8 +1,8 @@ -.select { +.dx-select { position: relative; } -.select-trigger { +.dx-select-trigger { position: relative; display: flex; box-sizing: border-box; @@ -25,15 +25,15 @@ transition: background-color 100ms ease-out; } -.select-trigger span[data-placeholder="true"] { +.dx-select-trigger span[data-placeholder="true"] { color: var(--secondary-color-5); } -.select[data-state="open"] .select-trigger { +.dx-select[data-state="open"] .dx-select-trigger { pointer-events: none; } -.select-expand-icon { +.dx-select-expand-icon { width: 20px; height: 20px; fill: none; @@ -43,7 +43,7 @@ stroke-width: 2; } -.select-check-icon { +.dx-select-check-icon { width: 1rem; height: 1rem; fill: none; @@ -53,20 +53,20 @@ stroke-width: 2; } -.select[data-disabled="true"] .select-trigger { +.dx-select[data-disabled="true"] .dx-select-trigger { color: var(--secondary-color-5); cursor: not-allowed; } -.select-trigger:hover:not([data-disabled="true"]), -.select-trigger:focus-visible { +.dx-select-trigger:hover:not([data-disabled="true"]), +.dx-select-trigger:focus-visible { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-5)); color: var(--secondary-color-1); outline: none; } -.select-list { +.dx-select-list { position: absolute; z-index: 1000; top: 100%; @@ -86,12 +86,12 @@ will-change: transform, opacity; } -.select-list[data-state="closed"] { - animation: select-list-animate-out 150ms ease-in forwards; +.dx-select-list[data-state="closed"] { + animation: dx-select-list-animate-out 150ms ease-in forwards; pointer-events: none; } -@keyframes select-list-animate-out { +@keyframes dx-select-list-animate-out { 0% { opacity: 1; transform: scale(1) translateY(0); @@ -103,12 +103,12 @@ } } -.select-list[data-state="open"] { - animation: select-list-animate-in 150ms ease-out forwards; +.dx-select-list[data-state="open"] { + animation: dx-select-list-animate-in 150ms ease-out forwards; pointer-events: auto; } -@keyframes select-list-animate-in { +@keyframes dx-select-list-animate-in { 0% { opacity: 0; transform: scale(0.95) translateY(-2px); @@ -120,7 +120,7 @@ } } -.select-option { +.dx-select-option { display: flex; align-items: center; justify-content: space-between; @@ -130,20 +130,20 @@ font-size: 14px; } -.select-option[data-disabled="true"] { +.dx-select-option[data-disabled="true"] { color: var(--secondary-color-5); cursor: not-allowed; } -.select-option:hover:not([data-disabled="true"]), -.select-option:focus-visible { +.dx-select-option:hover:not([data-disabled="true"]), +.dx-select-option:focus-visible { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-7)); color: var(--secondary-color-1); outline: none; } -.select-group-label { +.dx-select-group-label { padding: 4px 12px; color: var(--secondary-color-5); font-size: 0.75rem; diff --git a/preview/src/components/separator/component.rs b/preview/src/components/separator/component.rs index af195e1d..125328b0 100644 --- a/preview/src/components/separator/component.rs +++ b/preview/src/components/separator/component.rs @@ -6,7 +6,7 @@ pub fn Separator(props: SeparatorProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } separator::Separator { - class: "separator", + class: "dx-separator", horizontal: props.horizontal, decorative: props.decorative, attributes: props.attributes, diff --git a/preview/src/components/separator/style.css b/preview/src/components/separator/style.css index cfff431d..40b1bbee 100644 --- a/preview/src/components/separator/style.css +++ b/preview/src/components/separator/style.css @@ -1,13 +1,13 @@ -.separator { +.dx-separator { background-color: var(--light, var(--primary-color-6)) var(--dark, var(--primary-color-7)); } -.separator[data-orientation="horizontal"] { +.dx-separator[data-orientation="horizontal"] { width: 100%; height: 1px; } -.separator[data-orientation="vertical"] { +.dx-separator[data-orientation="vertical"] { width: 1px; height: 100%; } diff --git a/preview/src/components/sheet/component.rs b/preview/src/components/sheet/component.rs index c7b091a2..d4ab030a 100644 --- a/preview/src/components/sheet/component.rs +++ b/preview/src/components/sheet/component.rs @@ -44,7 +44,7 @@ fn SheetRoot(props: DialogRootProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } dialog::DialogRoot { - class: "sheet-root", + class: "dx-sheet-root", "data-slot": "sheet-root", id: props.id, is_modal: props.is_modal, @@ -66,8 +66,8 @@ pub fn SheetContent( children: Element, ) -> Element { let class = class - .map(|c| format!("sheet {c}")) - .unwrap_or("sheet".to_string()); + .map(|c| format!("dx-sheet {c}")) + .unwrap_or("dx-sheet".to_string()); rsx! { dialog::DialogContent { @@ -77,9 +77,9 @@ pub fn SheetContent( "data-side": side.as_str(), attributes, {children} - SheetClose { class: "sheet-close", + SheetClose { class: "dx-sheet-close", svg { - class: "sheet-close-icon", + class: "dx-sheet-close-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", path { d: "M18 6 6 18" } @@ -96,7 +96,7 @@ pub fn SheetHeader( children: Element, ) -> Element { rsx! { - div { class: "sheet-header", "data-slot": "sheet-header", ..attributes, {children} } + div { class: "dx-sheet-header", "data-slot": "sheet-header", ..attributes, {children} } } } @@ -106,7 +106,7 @@ pub fn SheetFooter( children: Element, ) -> Element { rsx! { - div { class: "sheet-footer", "data-slot": "sheet-footer", ..attributes, {children} } + div { class: "dx-sheet-footer", "data-slot": "sheet-footer", ..attributes, {children} } } } @@ -115,7 +115,7 @@ pub fn SheetTitle(props: DialogTitleProps) -> Element { rsx! { dialog::DialogTitle { id: props.id, - class: "sheet-title", + class: "dx-sheet-title", "data-slot": "sheet-title", attributes: props.attributes, {props.children} @@ -128,7 +128,7 @@ pub fn SheetDescription(props: DialogDescriptionProps) -> Element { rsx! { dialog::DialogDescription { id: props.id, - class: "sheet-description", + class: "dx-sheet-description", "data-slot": "sheet-description", attributes: props.attributes, {props.children} diff --git a/preview/src/components/sheet/style.css b/preview/src/components/sheet/style.css index adc03ce9..b44b7edb 100644 --- a/preview/src/components/sheet/style.css +++ b/preview/src/components/sheet/style.css @@ -1,5 +1,5 @@ /* Sheet Root */ -.sheet-root { +.dx-sheet-root { position: fixed; z-index: 1000; background: rgb(0 0 0 / 50%); @@ -8,16 +8,16 @@ will-change: opacity; } -.sheet-root[data-state="closed"] { - animation: sheet-root-out 300ms ease-in forwards; +.dx-sheet-root[data-state="closed"] { + animation: dx-sheet-root-out 300ms ease-in forwards; pointer-events: none; } -.sheet-root[data-state="open"] { - animation: sheet-root-in 300ms ease-out forwards; +.dx-sheet-root[data-state="open"] { + animation: dx-sheet-root-in 300ms ease-out forwards; } -@keyframes sheet-root-in { +@keyframes dx-sheet-root-in { from { opacity: 0; } @@ -27,7 +27,7 @@ } } -@keyframes sheet-root-out { +@keyframes dx-sheet-root-out { from { opacity: 1; } @@ -37,7 +37,7 @@ } } -.sheet { +.dx-sheet { position: fixed; z-index: 1001; display: flex; @@ -52,77 +52,77 @@ will-change: transform; } -.sheet[data-side="right"], -.sheet[data-side="left"] { +.dx-sheet[data-side="right"], +.dx-sheet[data-side="left"] { top: 0; bottom: 0; width: 75%; max-width: 24rem; } -.sheet[data-side="right"] { +.dx-sheet[data-side="right"] { right: 0; border-left: 1px solid var(--primary-color-6); transform: translateX(100%); } -.sheet[data-side="left"] { +.dx-sheet[data-side="left"] { left: 0; border-right: 1px solid var(--primary-color-6); transform: translateX(-100%); } -.sheet[data-side="top"], -.sheet[data-side="bottom"] { +.dx-sheet[data-side="top"], +.dx-sheet[data-side="bottom"] { right: 0; left: 0; } -.sheet[data-side="top"] { +.dx-sheet[data-side="top"] { top: 0; border-bottom: 1px solid var(--primary-color-6); transform: translateY(-100%); } -.sheet[data-side="bottom"] { +.dx-sheet[data-side="bottom"] { bottom: 0; border-top: 1px solid var(--primary-color-6); transform: translateY(100%); } -.sheet-root[data-state="open"] .sheet[data-side="right"] { - animation: slide-in-right 500ms ease-out forwards; +.dx-sheet-root[data-state="open"] .dx-sheet[data-side="right"] { + animation: dx-slide-in-right 500ms ease-out forwards; } -.sheet-root[data-state="open"] .sheet[data-side="left"] { - animation: slide-in-left 500ms ease-out forwards; +.dx-sheet-root[data-state="open"] .dx-sheet[data-side="left"] { + animation: dx-slide-in-left 500ms ease-out forwards; } -.sheet-root[data-state="open"] .sheet[data-side="top"] { - animation: slide-in-top 500ms ease-out forwards; +.dx-sheet-root[data-state="open"] .dx-sheet[data-side="top"] { + animation: dx-slide-in-top 500ms ease-out forwards; } -.sheet-root[data-state="open"] .sheet[data-side="bottom"] { - animation: slide-in-bottom 500ms ease-out forwards; +.dx-sheet-root[data-state="open"] .dx-sheet[data-side="bottom"] { + animation: dx-slide-in-bottom 500ms ease-out forwards; } -.sheet-root[data-state="closed"] .sheet[data-side="right"] { - animation: slide-out-right 300ms ease-in forwards; +.dx-sheet-root[data-state="closed"] .dx-sheet[data-side="right"] { + animation: dx-slide-out-right 300ms ease-in forwards; } -.sheet-root[data-state="closed"] .sheet[data-side="left"] { - animation: slide-out-left 300ms ease-in forwards; +.dx-sheet-root[data-state="closed"] .dx-sheet[data-side="left"] { + animation: dx-slide-out-left 300ms ease-in forwards; } -.sheet-root[data-state="closed"] .sheet[data-side="top"] { - animation: slide-out-top 300ms ease-in forwards; +.dx-sheet-root[data-state="closed"] .dx-sheet[data-side="top"] { + animation: dx-slide-out-top 300ms ease-in forwards; } -.sheet-root[data-state="closed"] .sheet[data-side="bottom"] { - animation: slide-out-bottom 300ms ease-in forwards; +.dx-sheet-root[data-state="closed"] .dx-sheet[data-side="bottom"] { + animation: dx-slide-out-bottom 300ms ease-in forwards; } -@keyframes slide-in-right { +@keyframes dx-slide-in-right { from { transform: translateX(100%); } @@ -132,7 +132,7 @@ } } -@keyframes slide-out-right { +@keyframes dx-slide-out-right { from { transform: translateX(0); } @@ -142,7 +142,7 @@ } } -@keyframes slide-in-left { +@keyframes dx-slide-in-left { from { transform: translateX(-100%); } @@ -152,7 +152,7 @@ } } -@keyframes slide-out-left { +@keyframes dx-slide-out-left { from { transform: translateX(0); } @@ -162,7 +162,7 @@ } } -@keyframes slide-in-top { +@keyframes dx-slide-in-top { from { transform: translateY(-100%); } @@ -172,7 +172,7 @@ } } -@keyframes slide-out-top { +@keyframes dx-slide-out-top { from { transform: translateY(0); } @@ -182,7 +182,7 @@ } } -@keyframes slide-in-bottom { +@keyframes dx-slide-in-bottom { from { transform: translateY(100%); } @@ -192,7 +192,7 @@ } } -@keyframes slide-out-bottom { +@keyframes dx-slide-out-bottom { from { transform: translateY(0); } @@ -202,14 +202,14 @@ } } -.sheet-header { +.dx-sheet-header { display: flex; flex-direction: column; padding: 1rem; gap: 0.375rem; } -.sheet-footer { +.dx-sheet-footer { display: flex; flex-direction: column; padding: 1rem; @@ -217,20 +217,20 @@ gap: 0.5rem; } -.sheet-title { +.dx-sheet-title { margin: 0; color: var(--secondary-color-4); font-size: 1.125rem; font-weight: 600; } -.sheet-description { +.dx-sheet-description { margin: 0; color: var(--secondary-color-5); font-size: 0.875rem; } -.sheet-close { +.dx-sheet-close { position: absolute; top: 1rem; right: 1rem; @@ -248,11 +248,11 @@ transition: color 150ms ease, background-color 150ms ease; } -.sheet-close:hover { +.dx-sheet-close:hover { color: var(--secondary-color-4); } -.sheet-close-icon { +.dx-sheet-close-icon { width: 20px; height: 20px; fill: none; diff --git a/preview/src/components/sidebar/component.rs b/preview/src/components/sidebar/component.rs index b84e6a1b..aa9331a9 100644 --- a/preview/src/components/sidebar/component.rs +++ b/preview/src/components/sidebar/component.rs @@ -232,14 +232,14 @@ pub fn SidebarProvider( let sidebar_style = format!( r#" - --sidebar-width: {SIDEBAR_WIDTH}; - --sidebar-width-mobile: {SIDEBAR_WIDTH_MOBILE}; - --sidebar-width-icon: {SIDEBAR_WIDTH_ICON} + --dx-sidebar-width: {SIDEBAR_WIDTH}; + --dx-sidebar-width-mobile: {SIDEBAR_WIDTH_MOBILE}; + --dx-sidebar-width-icon: {SIDEBAR_WIDTH_ICON} "# ); let base = attributes!(div { - class: "sidebar-wrapper", + class: "dx-sidebar-wrapper", "data-slot": "sidebar-wrapper", style: sidebar_style, }); @@ -271,7 +271,7 @@ pub fn Sidebar( if collapsible == SidebarCollapsible::None { let base = attributes!(div { - class: "sidebar sidebar-static", + class: "dx-sidebar dx-sidebar-static", "data-slot": "sidebar", }); let merged = merge_attributes(vec![base, attributes]); @@ -293,15 +293,15 @@ pub fn Sidebar( on_open_change: move |v| ctx.set_open_mobile(v), SheetContent { side: sheet_side, - class: "sidebar-sheet", + class: "dx-sidebar-sheet", "data-sidebar": "sidebar", "data-slot": "sidebar", "data-mobile": "true", - SheetHeader { class: "sr-only", + SheetHeader { class: "dx-sr-only", SheetTitle { "Sidebar" } SheetDescription { "Displays the mobile sidebar." } } - div { class: "sidebar-mobile-inner", {children} } + div { class: "dx-sidebar-mobile-inner", {children} } } } }; @@ -314,24 +314,24 @@ pub fn Sidebar( }; let container_base = attributes!(div { - class: "sidebar-container", + class: "dx-sidebar-container", "data-slot": "sidebar-container", }); let container_attrs = merge_attributes(vec![container_base, attributes]); rsx! { div { - class: "sidebar-desktop", + class: "dx-sidebar-desktop", "data-state": state().as_str(), "data-collapsible": collapsible_str, "data-variant": variant.as_str(), "data-side": side.as_str(), "data-slot": "sidebar", - div { class: "sidebar-gap", "data-slot": "sidebar-gap" } + div { class: "dx-sidebar-gap", "data-slot": "sidebar-gap" } div { ..container_attrs, div { - class: "sidebar-inner", + class: "dx-sidebar-inner", "data-sidebar": "sidebar", "data-slot": "sidebar-inner", {children} @@ -351,7 +351,7 @@ pub fn SidebarTrigger( let ctx = use_sidebar(); let base = attributes!(button { - class: "sidebar-trigger", + class: "dx-sidebar-trigger", "data-sidebar": "trigger", "data-slot": "sidebar-trigger", }); @@ -368,7 +368,7 @@ pub fn SidebarTrigger( }, attributes: merged, svg { - class: "sidebar-trigger-icon", + class: "dx-sidebar-trigger-icon", view_box: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", fill: "none", @@ -385,7 +385,7 @@ pub fn SidebarTrigger( } path { d: "M9 3v18" } } - span { class: "sr-only", "Toggle Sidebar" } + span { class: "dx-sr-only", "Toggle Sidebar" } } } } @@ -395,7 +395,7 @@ pub fn SidebarRail(#[props(extends = GlobalAttributes)] attributes: Vec Element { let base = attributes!(main { - class: "sidebar-inset", + class: "dx-sidebar-inset", "data-slot": "sidebar-inset", }); let merged = merge_attributes(vec![base, attributes]); @@ -434,7 +434,7 @@ pub fn SidebarHeader( children: Element, ) -> Element { let base = attributes!(div { - class: "sidebar-header", + class: "dx-sidebar-header", "data-slot": "sidebar-header", "data-sidebar": "header", }); @@ -451,7 +451,7 @@ pub fn SidebarContent( children: Element, ) -> Element { let base = attributes!(div { - class: "sidebar-content", + class: "dx-sidebar-content", "data-slot": "sidebar-content", "data-sidebar": "content", }); @@ -468,7 +468,7 @@ pub fn SidebarFooter( children: Element, ) -> Element { let base = attributes!(div { - class: "sidebar-footer", + class: "dx-sidebar-footer", "data-slot": "sidebar-footer", "data-sidebar": "footer", }); @@ -486,7 +486,7 @@ pub fn SidebarSeparator( #[props(extends = GlobalAttributes)] attributes: Vec, ) -> Element { let base = attributes!(div { - class: "sidebar-separator", + class: "dx-sidebar-separator", "data-slot": "sidebar-separator", "data-sidebar": "separator", }); @@ -503,7 +503,7 @@ pub fn SidebarGroup( children: Element, ) -> Element { let base = attributes!(div { - class: "sidebar-group", + class: "dx-sidebar-group", "data-slot": "sidebar-group", "data-sidebar": "group", }); @@ -521,7 +521,7 @@ pub fn SidebarGroupLabel( children: Element, ) -> Element { let base = attributes!(div { - class: "sidebar-group-label", + class: "dx-sidebar-group-label", "data-slot": "sidebar-group-label", "data-sidebar": "group-label", }); @@ -543,7 +543,7 @@ pub fn SidebarGroupAction( children: Element, ) -> Element { let base = attributes!(button { - class: "sidebar-group-action", + class: "dx-sidebar-group-action", "data-slot": "sidebar-group-action", "data-sidebar": "group-action", }); @@ -564,7 +564,7 @@ pub fn SidebarGroupContent( children: Element, ) -> Element { let base = attributes!(div { - class: "sidebar-group-content", + class: "dx-sidebar-group-content", "data-slot": "sidebar-group-content", "data-sidebar": "group-content", }); @@ -581,7 +581,7 @@ pub fn SidebarMenu( children: Element, ) -> Element { let base = attributes!(ul { - class: "sidebar-menu", + class: "dx-sidebar-menu", "data-slot": "sidebar-menu", "data-sidebar": "menu", }); @@ -598,7 +598,7 @@ pub fn SidebarMenuItem( children: Element, ) -> Element { let base = attributes!(li { - class: "sidebar-menu-item", + class: "dx-sidebar-menu-item", "data-slot": "sidebar-menu-item", "data-sidebar": "menu-item", }); @@ -660,7 +660,7 @@ pub fn SidebarMenuButton( let state = ctx.state; let base = attributes!(button { - class: "sidebar-menu-button", + class: "dx-sidebar-menu-button", "data-slot": "sidebar-menu-button", "data-sidebar": "menu-button", "data-size": size.as_str(), @@ -713,7 +713,7 @@ pub fn SidebarMenuAction( children: Element, ) -> Element { let base = attributes!(button { - class: "sidebar-menu-action", + class: "dx-sidebar-menu-action", "data-slot": "sidebar-menu-action", "data-sidebar": "menu-action", "data-show-on-hover": if show_on_hover { "true" } else { "false" }, @@ -735,7 +735,7 @@ pub fn SidebarMenuBadge( children: Element, ) -> Element { let base = attributes!(div { - class: "sidebar-menu-badge", + class: "dx-sidebar-menu-badge", "data-slot": "sidebar-menu-badge", "data-sidebar": "menu-badge", }); @@ -752,7 +752,7 @@ pub fn SidebarMenuSkeleton( #[props(extends = GlobalAttributes)] attributes: Vec, ) -> Element { let base = attributes!(div { - class: "sidebar-menu-skeleton", + class: "dx-sidebar-menu-skeleton", "data-slot": "sidebar-menu-skeleton", "data-sidebar": "menu-skeleton", }); @@ -762,9 +762,9 @@ pub fn SidebarMenuSkeleton( div { ..merged, if show_icon { - div { class: "skeleton sidebar-menu-skeleton-icon" } + div { class: "dx-skeleton dx-sidebar-menu-skeleton-icon" } } - div { class: "skeleton sidebar-menu-skeleton-text", width: "70%" } + div { class: "dx-skeleton dx-sidebar-menu-skeleton-text", width: "70%" } } } } @@ -775,7 +775,7 @@ pub fn SidebarMenuSub( children: Element, ) -> Element { let base = attributes!(ul { - class: "sidebar-menu-sub", + class: "dx-sidebar-menu-sub", "data-slot": "sidebar-menu-sub", "data-sidebar": "menu-sub", }); @@ -792,7 +792,7 @@ pub fn SidebarMenuSubItem( children: Element, ) -> Element { let base = attributes!(li { - class: "sidebar-menu-sub-item", + class: "dx-sidebar-menu-sub-item", "data-slot": "sidebar-menu-sub-item", "data-sidebar": "menu-sub-item", }); @@ -829,7 +829,7 @@ pub fn SidebarMenuSubButton( children: Element, ) -> Element { let base = attributes!(a { - class: "sidebar-menu-sub-button", + class: "dx-sidebar-menu-sub-button", "data-slot": "sidebar-menu-sub-button", "data-sidebar": "menu-sub-button", "data-size": size.as_str(), diff --git a/preview/src/components/sidebar/style.css b/preview/src/components/sidebar/style.css index fe3f9bb9..d81b40c0 100644 --- a/preview/src/components/sidebar/style.css +++ b/preview/src/components/sidebar/style.css @@ -1,5 +1,5 @@ /* TODO: abstract as Utilitiy class */ -.sr-only { +.dx-sr-only { position: absolute; overflow: hidden; width: 1px; @@ -12,15 +12,15 @@ } :root { - --sidebar-background: var(--primary-color-2); - --sidebar-foreground: var(--secondary-color-4); - --sidebar-border: var(--primary-color-6); - --sidebar-accent: var(--primary-color-4); - --sidebar-accent-foreground: var(--secondary-color-4); - --sidebar-ring: var(--primary-color-7); + --dx-sidebar-background: var(--primary-color-2); + --dx-sidebar-foreground: var(--secondary-color-4); + --dx-sidebar-border: var(--primary-color-6); + --dx-sidebar-accent: var(--primary-color-4); + --dx-sidebar-accent-foreground: var(--secondary-color-4); + --dx-sidebar-ring: var(--primary-color-7); } -.sidebar-wrapper { +.dx-sidebar-wrapper { display: flex; overflow: hidden; width: 100%; @@ -29,154 +29,154 @@ } @media (width >=768px) { - .sidebar-wrapper:has(.sidebar-desktop[data-side="right"]) { + .dx-sidebar-wrapper:has(.dx-sidebar-desktop[data-side="right"]) { flex-direction: row-reverse; } - .sidebar-wrapper:has(.sidebar-desktop[data-variant="inset"]) { - background: var(--sidebar-background); + .dx-sidebar-wrapper:has(.dx-sidebar-desktop[data-variant="inset"]) { + background: var(--dx-sidebar-background); } } -.sidebar-desktop { +.dx-sidebar-desktop { display: none; - color: var(--sidebar-foreground); + color: var(--dx-sidebar-foreground); } @media (width >=768px) { - .sidebar-desktop { + .dx-sidebar-desktop { display: block; } } -.sidebar-gap { +.dx-sidebar-gap { position: relative; - width: var(--sidebar-width); + width: var(--dx-sidebar-width); background: transparent; transition: width 200ms ease-out; } -[data-collapsible="icon"] .sidebar-gap { - width: var(--sidebar-width-icon); +[data-collapsible="icon"] .dx-sidebar-gap { + width: var(--dx-sidebar-width-icon); } -[data-variant="floating"] .sidebar-gap, -[data-variant="inset"] .sidebar-gap { - width: var(--sidebar-width); +[data-variant="floating"] .dx-sidebar-gap, +[data-variant="inset"] .dx-sidebar-gap { + width: var(--dx-sidebar-width); } -[data-variant="floating"][data-collapsible="icon"] .sidebar-gap, -[data-variant="inset"][data-collapsible="icon"] .sidebar-gap { - width: calc(var(--sidebar-width-icon) + 1rem); +[data-variant="floating"][data-collapsible="icon"] .dx-sidebar-gap, +[data-variant="inset"][data-collapsible="icon"] .dx-sidebar-gap { + width: calc(var(--dx-sidebar-width-icon) + 1rem); } -[data-collapsible="offcanvas"] .sidebar-gap { +[data-collapsible="offcanvas"] .dx-sidebar-gap { width: 0; } -.sidebar-container { +.dx-sidebar-container { position: fixed; z-index: 10; top: 0; bottom: 0; display: none; - width: var(--sidebar-width); + width: var(--dx-sidebar-width); height: 100svh; box-sizing: border-box; transition: left 200ms ease-out, right 200ms ease-out, width 200ms ease-out; } @media (width >=768px) { - .sidebar-container { + .dx-sidebar-container { display: flex; } } -[data-side="left"] .sidebar-container { +[data-side="left"] .dx-sidebar-container { left: 0; } -[data-side="left"][data-collapsible="offcanvas"] .sidebar-container { - left: calc(var(--sidebar-width) * -1); +[data-side="left"][data-collapsible="offcanvas"] .dx-sidebar-container { + left: calc(var(--dx-sidebar-width) * -1); } -[data-side="right"] .sidebar-container { +[data-side="right"] .dx-sidebar-container { right: 0; } -[data-side="right"][data-collapsible="offcanvas"] .sidebar-container { - right: calc(var(--sidebar-width) * -1); +[data-side="right"][data-collapsible="offcanvas"] .dx-sidebar-container { + right: calc(var(--dx-sidebar-width) * -1); } -[data-collapsible="icon"] .sidebar-container { +[data-collapsible="icon"] .dx-sidebar-container { overflow: visible; - width: var(--sidebar-width-icon); + width: var(--dx-sidebar-width-icon); } -[data-collapsible="icon"] .sidebar-inner { +[data-collapsible="icon"] .dx-sidebar-inner { overflow: visible; } -[data-variant="sidebar"][data-side="left"] .sidebar-container { - border-right: 1px solid var(--sidebar-border); +[data-variant="sidebar"][data-side="left"] .dx-sidebar-container { + border-right: 1px solid var(--dx-sidebar-border); } -[data-variant="sidebar"][data-side="right"] .sidebar-container { - border-left: 1px solid var(--sidebar-border); +[data-variant="sidebar"][data-side="right"] .dx-sidebar-container { + border-left: 1px solid var(--dx-sidebar-border); } -[data-variant="floating"] .sidebar-container, -[data-variant="inset"] .sidebar-container { +[data-variant="floating"] .dx-sidebar-container, +[data-variant="inset"] .dx-sidebar-container { padding: 0.5rem; } -[data-variant="floating"][data-collapsible="icon"] .sidebar-container, -[data-variant="inset"][data-collapsible="icon"] .sidebar-container { - width: calc(var(--sidebar-width-icon) + 1rem + 2px); +[data-variant="floating"][data-collapsible="icon"] .dx-sidebar-container, +[data-variant="inset"][data-collapsible="icon"] .dx-sidebar-container { + width: calc(var(--dx-sidebar-width-icon) + 1rem + 2px); } -.sidebar-inner { +.dx-sidebar-inner { display: flex; width: 100%; height: 100%; box-sizing: border-box; flex-direction: column; - background: var(--sidebar-background); + background: var(--dx-sidebar-background); } -[data-variant="floating"] .sidebar-inner { - border: 1px solid var(--sidebar-border); +[data-variant="floating"] .dx-sidebar-inner { + border: 1px solid var(--dx-sidebar-border); border-radius: 0.5rem; box-shadow: 0 1px 3px rgb(0 0 0 / 10%); } -.sidebar-static { +.dx-sidebar-static { display: flex; - width: var(--sidebar-width); + width: var(--dx-sidebar-width); height: 100%; flex-direction: column; - background: var(--sidebar-background); - color: var(--sidebar-foreground); + background: var(--dx-sidebar-background); + color: var(--dx-sidebar-foreground); } -.sidebar-sheet { - width: var(--sidebar-width-mobile) !important; +.dx-sidebar-sheet { + width: var(--dx-sidebar-width-mobile) !important; padding: 0 !important; - background: var(--sidebar-background); + background: var(--dx-sidebar-background); } -.sidebar-sheet>.sheet-close { +.dx-sidebar-sheet>.dx-sheet-close { display: none; } -.sidebar-mobile-inner { +.dx-sidebar-mobile-inner { display: flex; width: 100%; height: 100%; flex-direction: column; } -.sidebar-trigger { +.dx-sidebar-trigger { display: inline-flex; width: 1.75rem; height: 1.75rem; @@ -186,12 +186,12 @@ line-height: 0; } -.sidebar-trigger-icon { +.dx-sidebar-trigger-icon { width: 1rem; height: 1rem; } -.sidebar-rail { +.dx-sidebar-rail { position: absolute; z-index: 20; top: 0; @@ -207,12 +207,12 @@ } @media (width >=640px) { - .sidebar-rail { + .dx-sidebar-rail { display: flex; } } -.sidebar-rail::after { +.dx-sidebar-rail::after { position: absolute; top: 0; bottom: 0; @@ -221,49 +221,49 @@ content: ""; } -.sidebar-rail:hover::after { - background: var(--sidebar-border); +.dx-sidebar-rail:hover::after { + background: var(--dx-sidebar-border); } -[data-side="left"] .sidebar-rail { +[data-side="left"] .dx-sidebar-rail { right: -1rem; cursor: w-resize; } -[data-side="right"] .sidebar-rail { +[data-side="right"] .dx-sidebar-rail { left: 0; cursor: e-resize; } -[data-side="left"][data-state="collapsed"] .sidebar-rail { +[data-side="left"][data-state="collapsed"] .dx-sidebar-rail { cursor: e-resize; } -[data-side="right"][data-state="collapsed"] .sidebar-rail { +[data-side="right"][data-state="collapsed"] .dx-sidebar-rail { cursor: w-resize; } -[data-collapsible="offcanvas"] .sidebar-rail { +[data-collapsible="offcanvas"] .dx-sidebar-rail { transform: translateX(0); } -[data-collapsible="offcanvas"] .sidebar-rail::after { +[data-collapsible="offcanvas"] .dx-sidebar-rail::after { left: 100%; } -[data-collapsible="offcanvas"] .sidebar-rail:hover { - background: var(--sidebar-background); +[data-collapsible="offcanvas"] .dx-sidebar-rail:hover { + background: var(--dx-sidebar-background); } -[data-side="left"][data-collapsible="offcanvas"] .sidebar-rail { +[data-side="left"][data-collapsible="offcanvas"] .dx-sidebar-rail { right: -0.5rem; } -[data-side="right"][data-collapsible="offcanvas"] .sidebar-rail { +[data-side="right"][data-collapsible="offcanvas"] .dx-sidebar-rail { left: -0.5rem; } -.sidebar-inset { +.dx-sidebar-inset { position: relative; display: flex; width: 100%; @@ -272,34 +272,34 @@ background: var(--primary-color-1); } -[data-variant="inset"]~.sidebar-inset { +[data-variant="inset"]~.dx-sidebar-inset { border-radius: 0.75rem; margin: 0.5rem; margin-left: 0; box-shadow: 0 1px 3px rgb(0 0 0 / 10%); } -[data-variant="inset"][data-state="collapsed"]~.sidebar-inset { +[data-variant="inset"][data-state="collapsed"]~.dx-sidebar-inset { margin-left: 0.5rem; } -[data-variant="inset"][data-side="right"]~.sidebar-inset { +[data-variant="inset"][data-side="right"]~.dx-sidebar-inset { margin-right: 0; margin-left: 0.5rem; } -[data-variant="inset"][data-side="right"][data-state="collapsed"]~.sidebar-inset { +[data-variant="inset"][data-side="right"][data-state="collapsed"]~.dx-sidebar-inset { margin-right: 0.5rem; } -.sidebar-header { +.dx-sidebar-header { display: flex; flex-direction: column; padding: 0.5rem; gap: 0.5rem; } -.sidebar-content { +.dx-sidebar-content { display: flex; overflow: hidden auto; min-height: 0; @@ -308,24 +308,24 @@ gap: 0.5rem; } -[data-collapsible="icon"] .sidebar-content { +[data-collapsible="icon"] .dx-sidebar-content { overflow: visible; } -.sidebar-footer { +.dx-sidebar-footer { display: flex; flex-direction: column; padding: 0.5rem; gap: 0.5rem; } -.sidebar-separator { +.dx-sidebar-separator { width: auto; margin: 0 0.5rem; - background: var(--sidebar-border); + background: var(--dx-sidebar-border); } -.sidebar-group { +.dx-sidebar-group { position: relative; display: flex; min-width: 0; @@ -333,13 +333,13 @@ padding: 0.5rem; } -.sidebar-group-label { +.dx-sidebar-group-label { display: flex; height: 2rem; align-items: center; padding: 0 0.5rem; border-radius: 0.375rem; - color: var(--sidebar-foreground); + color: var(--dx-sidebar-foreground); font-size: 0.75rem; font-weight: 500; opacity: 0.7; @@ -347,18 +347,18 @@ transition: margin 200ms ease-out, opacity 200ms ease-out; } -.sidebar-group-label svg { +.dx-sidebar-group-label svg { width: 1rem; height: 1rem; flex-shrink: 0; } -[data-collapsible="icon"] .sidebar-group-label { +[data-collapsible="icon"] .dx-sidebar-group-label { margin-top: -2rem; opacity: 0; } -.sidebar-group-action { +.dx-sidebar-group-action { position: absolute; top: 0.875rem; right: 0.75rem; @@ -371,49 +371,49 @@ border-radius: 0.375rem; aspect-ratio: 1; background: transparent; - color: var(--sidebar-foreground); + color: var(--dx-sidebar-foreground); cursor: pointer; outline: none; transition: transform 150ms ease-out, opacity 200ms ease-out, visibility 0ms 0ms; } -.sidebar-group-action:hover { - background: var(--sidebar-accent); - color: var(--sidebar-accent-foreground); +.dx-sidebar-group-action:hover { + background: var(--dx-sidebar-accent); + color: var(--dx-sidebar-accent-foreground); } -.sidebar-group-action svg { +.dx-sidebar-group-action svg { width: 1rem; height: 1rem; flex-shrink: 0; } /* Increase hit area on mobile */ -.sidebar-group-action::after { +.dx-sidebar-group-action::after { position: absolute; content: ""; inset: -0.5rem; } @media (width >=768px) { - .sidebar-group-action::after { + .dx-sidebar-group-action::after { display: none; } } -[data-collapsible="icon"] .sidebar-group-action { +[data-collapsible="icon"] .dx-sidebar-group-action { opacity: 0; pointer-events: none; transition: transform 150ms ease-out, opacity 200ms ease-out, visibility 0ms 200ms; visibility: hidden; } -.sidebar-group-content { +.dx-sidebar-group-content { width: 100%; font-size: 0.875rem; } -.sidebar-menu { +.dx-sidebar-menu { display: flex; width: 100%; min-width: 0; @@ -424,11 +424,11 @@ list-style: none; } -.sidebar-menu-item { +.dx-sidebar-menu-item { position: relative; } -.sidebar-menu-button[data-sidebar="menu-button"] { +.dx-sidebar-menu-button[data-sidebar="menu-button"] { display: flex; overflow: hidden; width: 100%; @@ -438,7 +438,7 @@ border: none; border-radius: 0.375rem; background: transparent; - color: var(--sidebar-foreground); + color: var(--dx-sidebar-foreground); cursor: pointer; font-size: 0.875rem; gap: 0.5rem; @@ -448,93 +448,93 @@ transition: width 200ms ease-out, height 200ms ease-out, padding 200ms ease-out; } -.sidebar-menu-button[data-sidebar="menu-button"]:hover { - background: var(--sidebar-accent); - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-button[data-sidebar="menu-button"]:hover { + background: var(--dx-sidebar-accent); + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-button[data-sidebar="menu-button"]:focus-visible { - box-shadow: 0 0 0 2px var(--sidebar-ring); +.dx-sidebar-menu-button[data-sidebar="menu-button"]:focus-visible { + box-shadow: 0 0 0 2px var(--dx-sidebar-ring); } -.sidebar-menu-button[data-sidebar="menu-button"]:active { - background: var(--sidebar-accent); - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-button[data-sidebar="menu-button"]:active { + background: var(--dx-sidebar-accent); + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-button[data-sidebar="menu-button"]:disabled, -.sidebar-menu-button[data-sidebar="menu-button"][aria-disabled="true"] { +.dx-sidebar-menu-button[data-sidebar="menu-button"]:disabled, +.dx-sidebar-menu-button[data-sidebar="menu-button"][aria-disabled="true"] { opacity: 0.5; pointer-events: none; } -.sidebar-menu-button[data-sidebar="menu-button"][data-active="true"] { - background: var(--sidebar-accent); - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-active="true"] { + background: var(--dx-sidebar-accent); + color: var(--dx-sidebar-accent-foreground); font-weight: 500; } -.sidebar-menu-button[data-sidebar="menu-button"] svg { +.dx-sidebar-menu-button[data-sidebar="menu-button"] svg { width: 1rem; height: 1rem; flex-shrink: 0; } -.sidebar-menu-button[data-sidebar="menu-button"]>span:last-child { +.dx-sidebar-menu-button[data-sidebar="menu-button"]>span:last-child { overflow: hidden; text-overflow: ellipsis; transition: opacity 200ms ease-out; white-space: nowrap; } -.sidebar-desktop[data-collapsible="icon"] .sidebar-menu-button[data-sidebar="menu-button"]>span:last-child { +.dx-sidebar-desktop[data-collapsible="icon"] .dx-sidebar-menu-button[data-sidebar="menu-button"]>span:last-child { opacity: 0; } /* Size variants */ -.sidebar-menu-button[data-sidebar="menu-button"][data-size="default"] { +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-size="default"] { height: 2rem; font-size: 0.875rem; } -.sidebar-menu-button[data-sidebar="menu-button"][data-size="sm"] { +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-size="sm"] { height: 1.75rem; font-size: 0.75rem; } -.sidebar-menu-button[data-sidebar="menu-button"][data-size="lg"] { +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-size="lg"] { height: 3rem; font-size: 0.875rem; } -.sidebar-menu-button[data-sidebar="menu-button"][data-variant="outline"] { +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-variant="outline"] { background: var(--primary-color-1); - box-shadow: 0 0 0 1px var(--sidebar-border); + box-shadow: 0 0 0 1px var(--dx-sidebar-border); } -.sidebar-menu-button[data-sidebar="menu-button"][data-variant="outline"]:hover { - background: var(--sidebar-accent); - box-shadow: 0 0 0 1px var(--sidebar-accent); +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-variant="outline"]:hover { + background: var(--dx-sidebar-accent); + box-shadow: 0 0 0 1px var(--dx-sidebar-accent); } -.sidebar-desktop[data-collapsible="icon"] .sidebar-menu-button[data-sidebar="menu-button"] { +.dx-sidebar-desktop[data-collapsible="icon"] .dx-sidebar-menu-button[data-sidebar="menu-button"] { width: 2rem; height: 2rem; padding: 0.5rem; } -.sidebar-desktop[data-collapsible="icon"] .sidebar-menu-button[data-sidebar="menu-button"][data-size="lg"] { +.dx-sidebar-desktop[data-collapsible="icon"] .dx-sidebar-menu-button[data-sidebar="menu-button"][data-size="lg"] { padding: 0; } -.sidebar-desktop[data-collapsible="icon"] .sidebar-menu-button[data-sidebar="menu-button"]:has(> :first-child:is(svg, img)), -.sidebar-desktop[data-collapsible="icon"] .sidebar-menu-button[data-sidebar="menu-button"]:has(> :first-child:has(svg, img)) { +.dx-sidebar-desktop[data-collapsible="icon"] .dx-sidebar-menu-button[data-sidebar="menu-button"]:has(> :first-child:is(svg, img)), +.dx-sidebar-desktop[data-collapsible="icon"] .dx-sidebar-menu-button[data-sidebar="menu-button"]:has(> :first-child:has(svg, img)) { justify-content: center; gap: 0; } -.sidebar-desktop[data-collapsible="icon"] .sidebar-menu-button[data-sidebar="menu-button"]:has(> :first-child:is(svg, img))> :not(:first-child), -.sidebar-desktop[data-collapsible="icon"] .sidebar-menu-button[data-sidebar="menu-button"]:has(> :first-child:has(svg, img))> :not(:first-child) { +.dx-sidebar-desktop[data-collapsible="icon"] .dx-sidebar-menu-button[data-sidebar="menu-button"]:has(> :first-child:is(svg, img))> :not(:first-child), +.dx-sidebar-desktop[data-collapsible="icon"] .dx-sidebar-menu-button[data-sidebar="menu-button"]:has(> :first-child:has(svg, img))> :not(:first-child) { position: absolute; overflow: hidden; width: 1px; @@ -546,15 +546,15 @@ white-space: nowrap; } -.sidebar-desktop[data-collapsible="icon"] .sidebar-menu-button[data-sidebar="menu-button"] svg { +.dx-sidebar-desktop[data-collapsible="icon"] .dx-sidebar-menu-button[data-sidebar="menu-button"] svg { display: block; } -.sidebar-menu-item:has(.sidebar-menu-action[data-sidebar="menu-action"]) .sidebar-menu-button[data-sidebar="menu-button"] { +.dx-sidebar-menu-item:has(.dx-sidebar-menu-action[data-sidebar="menu-action"]) .dx-sidebar-menu-button[data-sidebar="menu-button"] { padding-right: 2rem; } -.sidebar-menu-action[data-sidebar="menu-action"] { +.dx-sidebar-menu-action[data-sidebar="menu-action"] { position: absolute; top: 0.375rem; right: 0.25rem; @@ -567,71 +567,71 @@ border-radius: 0.375rem; aspect-ratio: 1; background: transparent; - color: var(--sidebar-foreground); + color: var(--dx-sidebar-foreground); cursor: pointer; outline: none; transition: transform 150ms ease-out, opacity 200ms ease-out, visibility 0ms 0ms; } -.sidebar-menu-action[data-sidebar="menu-action"]:hover { - background: var(--sidebar-accent); - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-action[data-sidebar="menu-action"]:hover { + background: var(--dx-sidebar-accent); + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-action[data-sidebar="menu-action"] svg { +.dx-sidebar-menu-action[data-sidebar="menu-action"] svg { width: 1rem; height: 1rem; flex-shrink: 0; } -.sidebar-menu-action[data-sidebar="menu-action"]::after { +.dx-sidebar-menu-action[data-sidebar="menu-action"]::after { position: absolute; content: ""; inset: -0.5rem; } @media (width >=768px) { - .sidebar-menu-action[data-sidebar="menu-action"]::after { + .dx-sidebar-menu-action[data-sidebar="menu-action"]::after { display: none; } } -.sidebar-menu-button[data-sidebar="menu-button"][data-size="sm"]~.sidebar-menu-action[data-sidebar="menu-action"] { +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-size="sm"]~.dx-sidebar-menu-action[data-sidebar="menu-action"] { top: 0.25rem; } -.sidebar-menu-button[data-sidebar="menu-button"][data-size="default"]~.sidebar-menu-action[data-sidebar="menu-action"] { +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-size="default"]~.dx-sidebar-menu-action[data-sidebar="menu-action"] { top: 0.375rem; } -.sidebar-menu-button[data-sidebar="menu-button"][data-size="lg"]~.sidebar-menu-action[data-sidebar="menu-action"] { +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-size="lg"]~.dx-sidebar-menu-action[data-sidebar="menu-action"] { top: 0.625rem; } -[data-collapsible="icon"] .sidebar-menu-action[data-sidebar="menu-action"] { +[data-collapsible="icon"] .dx-sidebar-menu-action[data-sidebar="menu-action"] { opacity: 0; pointer-events: none; transition: transform 150ms ease-out, opacity 200ms ease-out, visibility 0ms 200ms; visibility: hidden; } -.sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"] { +.dx-sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"] { opacity: 0; } @media (width >=768px) { - .sidebar-menu-item:hover .sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"], - .sidebar-menu-item:focus-within .sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"], - .sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"][data-state="open"] { + .dx-sidebar-menu-item:hover .dx-sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"], + .dx-sidebar-menu-item:focus-within .dx-sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"], + .dx-sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"][data-state="open"] { opacity: 1; } } -.sidebar-menu-button[data-sidebar="menu-button"][data-active="true"]~.sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"] { - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-button[data-sidebar="menu-button"][data-active="true"]~.dx-sidebar-menu-action[data-sidebar="menu-action"][data-show-on-hover="true"] { + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-badge { +.dx-sidebar-menu-badge { position: absolute; right: 0.25rem; display: flex; @@ -641,7 +641,7 @@ justify-content: center; padding: 0 0.25rem; border-radius: 0.375rem; - color: var(--sidebar-foreground); + color: var(--dx-sidebar-foreground); font-size: 0.75rem; font-variant-numeric: tabular-nums; font-weight: 500; @@ -650,32 +650,32 @@ user-select: none; } -.sidebar-menu-button:hover~.sidebar-menu-badge { - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-button:hover~.dx-sidebar-menu-badge { + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-button[data-active="true"]~.sidebar-menu-badge { - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-button[data-active="true"]~.dx-sidebar-menu-badge { + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-button[data-size="sm"]~.sidebar-menu-badge { +.dx-sidebar-menu-button[data-size="sm"]~.dx-sidebar-menu-badge { top: 0.25rem; } -.sidebar-menu-button[data-size="default"]~.sidebar-menu-badge { +.dx-sidebar-menu-button[data-size="default"]~.dx-sidebar-menu-badge { top: 0.375rem; } -.sidebar-menu-button[data-size="lg"]~.sidebar-menu-badge { +.dx-sidebar-menu-button[data-size="lg"]~.dx-sidebar-menu-badge { top: 0.625rem; } -[data-collapsible="icon"] .sidebar-menu-badge { +[data-collapsible="icon"] .dx-sidebar-menu-badge { opacity: 0; pointer-events: none; } -.sidebar-menu-skeleton { +.dx-sidebar-menu-skeleton { display: flex; height: 2rem; align-items: center; @@ -684,22 +684,22 @@ gap: 0.5rem; } -.sidebar-menu-skeleton-icon { +.dx-sidebar-menu-skeleton-icon { width: 1rem; height: 1rem; border-radius: 0.375rem; } -.sidebar-menu-skeleton-text { +.dx-sidebar-menu-skeleton-text { height: 1rem; flex: 1; } -.sidebar-menu-sub { +.dx-sidebar-menu-sub { display: flex; flex-direction: column; padding: 0.125rem 0.625rem; - border-left: 1px solid var(--sidebar-border); + border-left: 1px solid var(--dx-sidebar-border); margin: 0 0.875rem; gap: 0.25rem; list-style: none; @@ -707,7 +707,7 @@ transition: opacity 200ms ease-out, max-height 200ms ease-out, padding 200ms ease-out, margin 200ms ease-out, visibility 0ms 0ms; } -[data-collapsible="icon"] .sidebar-menu-sub { +[data-collapsible="icon"] .dx-sidebar-menu-sub { overflow: hidden; max-height: 0; padding: 0; @@ -718,11 +718,11 @@ visibility: hidden; } -.sidebar-menu-sub-item { +.dx-sidebar-menu-sub-item { position: relative; } -.sidebar-menu-sub-button { +.dx-sidebar-menu-sub-button { display: flex; overflow: hidden; width: 100%; @@ -734,7 +734,7 @@ border: none; border-radius: 0.375rem; background: transparent; - color: var(--sidebar-foreground); + color: var(--dx-sidebar-foreground); cursor: pointer; font-size: 0.875rem; gap: 0.5rem; @@ -744,53 +744,53 @@ transition: opacity 200ms ease-out; } -.sidebar-menu-sub-button:hover { - background: var(--sidebar-accent); - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-sub-button:hover { + background: var(--dx-sidebar-accent); + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-sub-button:focus-visible { - box-shadow: 0 0 0 2px var(--sidebar-ring); +.dx-sidebar-menu-sub-button:focus-visible { + box-shadow: 0 0 0 2px var(--dx-sidebar-ring); } -.sidebar-menu-sub-button:active { - background: var(--sidebar-accent); - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-sub-button:active { + background: var(--dx-sidebar-accent); + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-sub-button:disabled, -.sidebar-menu-sub-button[aria-disabled="true"] { +.dx-sidebar-menu-sub-button:disabled, +.dx-sidebar-menu-sub-button[aria-disabled="true"] { opacity: 0.5; pointer-events: none; } -.sidebar-menu-sub-button[data-active="true"] { - background: var(--sidebar-accent); - color: var(--sidebar-accent-foreground); +.dx-sidebar-menu-sub-button[data-active="true"] { + background: var(--dx-sidebar-accent); + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-sub-button svg { +.dx-sidebar-menu-sub-button svg { width: 1rem; height: 1rem; flex-shrink: 0; - color: var(--sidebar-accent-foreground); + color: var(--dx-sidebar-accent-foreground); } -.sidebar-menu-sub-button>span:last-child { +.dx-sidebar-menu-sub-button>span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -.sidebar-menu-sub-button[data-size="sm"] { +.dx-sidebar-menu-sub-button[data-size="sm"] { font-size: 0.75rem; } -.sidebar-menu-sub-button[data-size="md"] { +.dx-sidebar-menu-sub-button[data-size="md"] { font-size: 0.875rem; } -[data-collapsible="icon"] .sidebar-menu-sub-button { +[data-collapsible="icon"] .dx-sidebar-menu-sub-button { opacity: 0; pointer-events: none; } diff --git a/preview/src/components/sidebar/variants/demo.css b/preview/src/components/sidebar/variants/demo.css index fe0185df..2d2b18ea 100644 --- a/preview/src/components/sidebar/variants/demo.css +++ b/preview/src/components/sidebar/variants/demo.css @@ -1,10 +1,10 @@ -.sidebar-icon { +.dx-sidebar-icon { width: 1rem; height: 1rem; flex-shrink: 0; } -.sidebar-info-block { +.dx-sidebar-info-block { display: grid; min-width: 0; flex: 1; @@ -13,36 +13,36 @@ text-align: left; } -.sidebar-info-title, -.sidebar-info-subtitle { +.dx-sidebar-info-title, +.dx-sidebar-info-subtitle { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -.sidebar-info-title { +.dx-sidebar-info-title { font-weight: 600; } -.sidebar-info-subtitle { +.dx-sidebar-info-subtitle { font-size: 0.75rem; opacity: 0.7; } -.sidebar-chevron { +.dx-sidebar-chevron { margin-left: auto; transition: transform 200ms ease-out; } -.sidebar-menu-button[data-open="true"] .sidebar-chevron { +.dx-sidebar-menu-button[data-open="true"] .dx-sidebar-chevron { transform: rotate(90deg); } -.sidebar-hide-on-collapse { +.dx-sidebar-hide-on-collapse { transition: opacity 200ms ease-out, max-height 200ms ease-out, padding 200ms ease-out, visibility 0ms 0ms; } -[data-collapsible="icon"] .sidebar-hide-on-collapse { +[data-collapsible="icon"] .dx-sidebar-hide-on-collapse { overflow: hidden; max-height: 0; padding: 0; @@ -52,50 +52,50 @@ visibility: hidden; } -.sidebar-menu :is(.dropdown-menu, .tooltip) { +.dx-sidebar-menu :is(.dx-dropdown-menu, .dx-tooltip) { display: block; width: 100%; } -.dropdown-menu-content .separator[data-orientation="horizontal"] { +.dx-dropdown-menu-content .dx-separator[data-orientation="horizontal"] { margin: 0.25rem 0; } -.sidebar-menu-item>.dropdown-menu:has(.sidebar-menu-action) { +.dx-sidebar-menu-item>.dx-dropdown-menu:has(.dx-sidebar-menu-action) { position: static; } -.sidebar-header .sidebar-menu-button[data-sidebar="menu-button"].dropdown-menu-trigger:not(:focus-visible), -.sidebar-footer .sidebar-menu-button[data-sidebar="menu-button"].dropdown-menu-trigger:not(:focus-visible) { +.dx-sidebar-header .dx-sidebar-menu-button[data-sidebar="menu-button"].dx-dropdown-menu-trigger:not(:focus-visible), +.dx-sidebar-footer .dx-sidebar-menu-button[data-sidebar="menu-button"].dx-dropdown-menu-trigger:not(:focus-visible) { box-shadow: none; } -.sidebar-sheet .sidebar-header .dropdown-menu-content { +.dx-sidebar-sheet .dx-sidebar-header .dx-dropdown-menu-content { margin-top: 4px; margin-bottom: 0; inset: 100% auto auto 0; } -.sidebar-sheet .sidebar-footer .dropdown-menu-content { +.dx-sidebar-sheet .dx-sidebar-footer .dx-dropdown-menu-content { margin-top: 0; margin-bottom: 4px; inset: auto auto 100% 0; } -.sidebar-menu-button[data-sidebar="menu-button"].collapsible-trigger:hover { +.dx-sidebar-menu-button[data-sidebar="menu-button"].dx-collapsible-trigger:hover { text-decoration: none; text-decoration-line: none; } @media (width >= 768px) { - .sidebar-desktop[data-side="left"] :is(.sidebar-header, .sidebar-menu-item:has(.sidebar-menu-action)) .dropdown-menu-content { + .dx-sidebar-desktop[data-side="left"] :is(.dx-sidebar-header, .dx-sidebar-menu-item:has(.dx-sidebar-menu-action)) .dx-dropdown-menu-content { top: 0; left: 100%; margin-top: 0; margin-left: 0.5rem; } - .sidebar-desktop[data-side="left"] .sidebar-footer .dropdown-menu-content { + .dx-sidebar-desktop[data-side="left"] .dx-sidebar-footer .dx-dropdown-menu-content { top: auto; bottom: 0; left: 100%; @@ -103,7 +103,7 @@ margin-left: 0.5rem; } - .sidebar-desktop[data-side="right"] :is(.sidebar-header, .sidebar-menu-item:has(.sidebar-menu-action)) .dropdown-menu-content { + .dx-sidebar-desktop[data-side="right"] :is(.dx-sidebar-header, .dx-sidebar-menu-item:has(.dx-sidebar-menu-action)) .dx-dropdown-menu-content { top: 0; right: 100%; left: auto; @@ -111,7 +111,7 @@ margin-right: 0.5rem; } - .sidebar-desktop[data-side="right"] .sidebar-footer .dropdown-menu-content { + .dx-sidebar-desktop[data-side="right"] .dx-sidebar-footer .dx-dropdown-menu-content { margin-right: 0.5rem; margin-bottom: 0; inset: auto 100% 0 auto; diff --git a/preview/src/components/sidebar/variants/floating/mod.rs b/preview/src/components/sidebar/variants/floating/mod.rs index 3fd67fb4..340a5754 100644 --- a/preview/src/components/sidebar/variants/floating/mod.rs +++ b/preview/src/components/sidebar/variants/floating/mod.rs @@ -212,9 +212,9 @@ fn TeamSwitcher(teams: &'static [Team]) -> Element { div { style: "display:flex; flex-shrink:0; align-items:center; justify-content:center; width:2rem; height:2rem; aspect-ratio:1; border-radius:0.5rem; background:var(--sidebar-accent); color:var(--sidebar-accent-foreground);", Icon {} } - div { class: "sidebar-info-block", - span { class: "sidebar-info-title", {teams[active_team()].name} } - span { class: "sidebar-info-subtitle", {teams[active_team()].plan} } + div { class: "dx-sidebar-info-block", + span { class: "dx-sidebar-info-title", {teams[active_team()].name} } + span { class: "dx-sidebar-info-subtitle", {teams[active_team()].plan} } } ChevronIcon {} } @@ -302,7 +302,7 @@ fn NavMain(items: &'static [NavMainItem]) -> Element { #[component] fn NavProjects(projects: &'static [Project]) -> Element { rsx! { - SidebarGroup { class: "sidebar-hide-on-collapse", + SidebarGroup { class: "dx-sidebar-hide-on-collapse", SidebarGroupLabel { "Projects" } SidebarMenu { for project in projects.iter() { @@ -320,7 +320,7 @@ fn NavProjects(projects: &'static [Project]) -> Element { as: move |attributes: Vec| rsx! { SidebarMenuAction { show_on_hover: true, attributes, Icon {} - span { class: "sr-only", "More" } + span { class: "dx-sr-only", "More" } } }, } @@ -379,9 +379,9 @@ fn NavUser() -> Element { } AvatarFallback { "DX" } } - div { class: "sidebar-info-block", - span { class: "sidebar-info-title", "Dioxus" } - span { class: "sidebar-info-subtitle", "m@example.com" } + div { class: "dx-sidebar-info-block", + span { class: "dx-sidebar-info-title", "Dioxus" } + span { class: "dx-sidebar-info-subtitle", "m@example.com" } } ChevronIcon {} } @@ -398,9 +398,9 @@ fn NavUser() -> Element { } AvatarFallback { "DX" } } - div { class: "sidebar-info-block", - span { class: "sidebar-info-title", "Dioxus" } - span { class: "sidebar-info-subtitle", "m@example.com" } + div { class: "dx-sidebar-info-block", + span { class: "dx-sidebar-info-title", "Dioxus" } + span { class: "dx-sidebar-info-subtitle", "m@example.com" } } } Separator { decorative: true } @@ -504,7 +504,7 @@ fn DemoSettingControls( } #[component] -fn Icon(#[props(default = "sidebar-icon")] class: &'static str) -> Element { +fn Icon(#[props(default = "dx-sidebar-icon")] class: &'static str) -> Element { rsx! { svg { xmlns: "http://www.w3.org/2000/svg", @@ -525,7 +525,7 @@ fn ChevronIcon() -> Element { rsx! { svg { xmlns: "http://www.w3.org/2000/svg", - class: "sidebar-icon sidebar-chevron", + class: "dx-sidebar-icon dx-sidebar-chevron", view_box: "0 0 24 24", fill: "none", stroke: "currentColor", diff --git a/preview/src/components/sidebar/variants/inset/mod.rs b/preview/src/components/sidebar/variants/inset/mod.rs index 5a8ed70d..b2dc5b92 100644 --- a/preview/src/components/sidebar/variants/inset/mod.rs +++ b/preview/src/components/sidebar/variants/inset/mod.rs @@ -212,9 +212,9 @@ fn TeamSwitcher(teams: &'static [Team]) -> Element { div { style: "display:flex; flex-shrink:0; align-items:center; justify-content:center; width:2rem; height:2rem; aspect-ratio:1; border-radius:0.5rem; background:var(--sidebar-accent); color:var(--sidebar-accent-foreground);", Icon {} } - div { class: "sidebar-info-block", - span { class: "sidebar-info-title", {teams[active_team()].name} } - span { class: "sidebar-info-subtitle", {teams[active_team()].plan} } + div { class: "dx-sidebar-info-block", + span { class: "dx-sidebar-info-title", {teams[active_team()].name} } + span { class: "dx-sidebar-info-subtitle", {teams[active_team()].plan} } } ChevronIcon {} } @@ -302,7 +302,7 @@ fn NavMain(items: &'static [NavMainItem]) -> Element { #[component] fn NavProjects(projects: &'static [Project]) -> Element { rsx! { - SidebarGroup { class: "sidebar-hide-on-collapse", + SidebarGroup { class: "dx-sidebar-hide-on-collapse", SidebarGroupLabel { "Projects" } SidebarMenu { for project in projects.iter() { @@ -320,7 +320,7 @@ fn NavProjects(projects: &'static [Project]) -> Element { as: move |attributes: Vec| rsx! { SidebarMenuAction { show_on_hover: true, attributes, Icon {} - span { class: "sr-only", "More" } + span { class: "dx-sr-only", "More" } } }, } @@ -379,9 +379,9 @@ fn NavUser() -> Element { } AvatarFallback { "DX" } } - div { class: "sidebar-info-block", - span { class: "sidebar-info-title", "Dioxus" } - span { class: "sidebar-info-subtitle", "m@example.com" } + div { class: "dx-sidebar-info-block", + span { class: "dx-sidebar-info-title", "Dioxus" } + span { class: "dx-sidebar-info-subtitle", "m@example.com" } } ChevronIcon {} } @@ -398,9 +398,9 @@ fn NavUser() -> Element { } AvatarFallback { "DX" } } - div { class: "sidebar-info-block", - span { class: "sidebar-info-title", "Dioxus" } - span { class: "sidebar-info-subtitle", "m@example.com" } + div { class: "dx-sidebar-info-block", + span { class: "dx-sidebar-info-title", "Dioxus" } + span { class: "dx-sidebar-info-subtitle", "m@example.com" } } } Separator { decorative: true } @@ -504,7 +504,7 @@ fn DemoSettingControls( } #[component] -fn Icon(#[props(default = "sidebar-icon")] class: &'static str) -> Element { +fn Icon(#[props(default = "dx-sidebar-icon")] class: &'static str) -> Element { rsx! { svg { xmlns: "http://www.w3.org/2000/svg", @@ -525,7 +525,7 @@ fn ChevronIcon() -> Element { rsx! { svg { xmlns: "http://www.w3.org/2000/svg", - class: "sidebar-icon sidebar-chevron", + class: "dx-sidebar-icon dx-sidebar-chevron", view_box: "0 0 24 24", fill: "none", stroke: "currentColor", diff --git a/preview/src/components/sidebar/variants/main/mod.rs b/preview/src/components/sidebar/variants/main/mod.rs index 8d09bc45..dfe299c9 100644 --- a/preview/src/components/sidebar/variants/main/mod.rs +++ b/preview/src/components/sidebar/variants/main/mod.rs @@ -212,9 +212,9 @@ fn TeamSwitcher(teams: &'static [Team]) -> Element { div { style: "display:flex; flex-shrink:0; align-items:center; justify-content:center; width:2rem; height:2rem; aspect-ratio:1; border-radius:0.5rem; background:var(--sidebar-accent); color:var(--sidebar-accent-foreground);", Icon {} } - div { class: "sidebar-info-block", - span { class: "sidebar-info-title", {teams[active_team()].name} } - span { class: "sidebar-info-subtitle", {teams[active_team()].plan} } + div { class: "dx-sidebar-info-block", + span { class: "dx-sidebar-info-title", {teams[active_team()].name} } + span { class: "dx-sidebar-info-subtitle", {teams[active_team()].plan} } } ChevronIcon {} } @@ -302,7 +302,7 @@ fn NavMain(items: &'static [NavMainItem]) -> Element { #[component] fn NavProjects(projects: &'static [Project]) -> Element { rsx! { - SidebarGroup { class: "sidebar-hide-on-collapse", + SidebarGroup { class: "dx-sidebar-hide-on-collapse", SidebarGroupLabel { "Projects" } SidebarMenu { for project in projects.iter() { @@ -320,7 +320,7 @@ fn NavProjects(projects: &'static [Project]) -> Element { as: move |attributes: Vec| rsx! { SidebarMenuAction { show_on_hover: true, attributes, Icon {} - span { class: "sr-only", "More" } + span { class: "dx-sr-only", "More" } } }, } @@ -379,9 +379,9 @@ fn NavUser() -> Element { } AvatarFallback { "DX" } } - div { class: "sidebar-info-block", - span { class: "sidebar-info-title", "Dioxus" } - span { class: "sidebar-info-subtitle", "m@example.com" } + div { class: "dx-sidebar-info-block", + span { class: "dx-sidebar-info-title", "Dioxus" } + span { class: "dx-sidebar-info-subtitle", "m@example.com" } } ChevronIcon {} } @@ -398,9 +398,9 @@ fn NavUser() -> Element { } AvatarFallback { "DX" } } - div { class: "sidebar-info-block", - span { class: "sidebar-info-title", "Dioxus" } - span { class: "sidebar-info-subtitle", "m@example.com" } + div { class: "dx-sidebar-info-block", + span { class: "dx-sidebar-info-title", "Dioxus" } + span { class: "dx-sidebar-info-subtitle", "m@example.com" } } } Separator { decorative: true } @@ -504,7 +504,7 @@ fn DemoSettingControls( } #[component] -fn Icon(#[props(default = "sidebar-icon")] class: &'static str) -> Element { +fn Icon(#[props(default = "dx-sidebar-icon")] class: &'static str) -> Element { rsx! { svg { xmlns: "http://www.w3.org/2000/svg", @@ -525,7 +525,7 @@ fn ChevronIcon() -> Element { rsx! { svg { xmlns: "http://www.w3.org/2000/svg", - class: "sidebar-icon sidebar-chevron", + class: "dx-sidebar-icon dx-sidebar-chevron", view_box: "0 0 24 24", fill: "none", stroke: "currentColor", diff --git a/preview/src/components/skeleton/component.rs b/preview/src/components/skeleton/component.rs index d8118890..889d4e7e 100644 --- a/preview/src/components/skeleton/component.rs +++ b/preview/src/components/skeleton/component.rs @@ -4,6 +4,6 @@ use dioxus::prelude::*; pub fn Skeleton(#[props(extends=GlobalAttributes)] attributes: Vec) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } - div { class: "skeleton", ..attributes } + div { class: "dx-skeleton", ..attributes } } } diff --git a/preview/src/components/skeleton/style.css b/preview/src/components/skeleton/style.css index 95be22ec..6230d4e8 100644 --- a/preview/src/components/skeleton/style.css +++ b/preview/src/components/skeleton/style.css @@ -1,10 +1,10 @@ -.skeleton { +.dx-skeleton { border-radius: 0.375rem; - animation: skeleton-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; + animation: dx-skeleton-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; background-color: var(--primary-color-5); } -@keyframes skeleton-pulse { +@keyframes dx-skeleton-pulse { 0%, 100% { opacity: 1; diff --git a/preview/src/components/slider/component.rs b/preview/src/components/slider/component.rs index 70b00f14..cd3919de 100644 --- a/preview/src/components/slider/component.rs +++ b/preview/src/components/slider/component.rs @@ -8,7 +8,7 @@ pub fn Slider(props: SliderProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } slider::Slider { - class: "slider", + class: "dx-slider", value: props.value, default_value: props.default_value, min: props.min, @@ -28,14 +28,14 @@ pub fn Slider(props: SliderProps) -> Element { #[component] pub fn SliderTrack(props: SliderTrackProps) -> Element { rsx! { - slider::SliderTrack { class: "slider-track", attributes: props.attributes, {props.children} } + slider::SliderTrack { class: "dx-slider-track", attributes: props.attributes, {props.children} } } } #[component] pub fn SliderRange(props: SliderRangeProps) -> Element { rsx! { - slider::SliderRange { class: "slider-range", attributes: props.attributes, {props.children} } + slider::SliderRange { class: "dx-slider-range", attributes: props.attributes, {props.children} } } } @@ -43,7 +43,7 @@ pub fn SliderRange(props: SliderRangeProps) -> Element { pub fn SliderThumb(props: SliderThumbProps) -> Element { rsx! { slider::SliderThumb { - class: "slider-thumb", + class: "dx-slider-thumb", index: props.index, attributes: props.attributes, {props.children} diff --git a/preview/src/components/slider/style.css b/preview/src/components/slider/style.css index e41bdd0a..5a90d839 100644 --- a/preview/src/components/slider/style.css +++ b/preview/src/components/slider/style.css @@ -1,4 +1,4 @@ -.slider { +.dx-slider { position: relative; display: flex; width: 200px; @@ -7,13 +7,13 @@ touch-action: none; } -.slider[data-orientation="vertical"] { +.dx-slider[data-orientation="vertical"] { width: auto; height: 200px; flex-direction: column; } -.slider-track { +.dx-slider-track { position: relative; height: 0.5rem; box-sizing: border-box; @@ -22,23 +22,23 @@ background: var(--primary-color-5); } -.slider[data-orientation="vertical"] .slider-track { +.dx-slider[data-orientation="vertical"] .dx-slider-track { width: 4px; height: 100%; } -.slider-range { +.dx-slider-range { position: absolute; height: 100%; border-radius: 9999px; background-color: var(--secondary-color-2); } -.slider[data-orientation="vertical"] .slider-range { +.dx-slider[data-orientation="vertical"] .dx-slider-range { width: 100%; } -.slider-thumb { +.dx-slider-thumb { all: unset; position: absolute; top: 50%; @@ -53,24 +53,24 @@ transition: border-color 150ms; } -.slider[data-orientation="vertical"] .slider-thumb { +.dx-slider[data-orientation="vertical"] .dx-slider-thumb { left: 50%; transform: translate(-50%, 50%); } -.slider-thumb:focus-visible[data-dragging="true"], -.slider-thumb:focus-visible, -.slider-thumb:hover { +.dx-slider-thumb:focus-visible[data-dragging="true"], +.dx-slider-thumb:focus-visible, +.dx-slider-thumb:hover { box-shadow: 0 0 0 4px color-mix(in oklab, var(--primary-color-7) 50%, transparent); transition: box-shadow 150ms; } -.slider[data-disabled="true"] { +.dx-slider[data-disabled="true"] { cursor: not-allowed; opacity: 0.5; } -.slider[data-disabled="true"] .slider-thumb { +.dx-slider[data-disabled="true"] .dx-slider-thumb { cursor: not-allowed; } diff --git a/preview/src/components/switch/component.rs b/preview/src/components/switch/component.rs index f63d7edd..ed5f765e 100644 --- a/preview/src/components/switch/component.rs +++ b/preview/src/components/switch/component.rs @@ -6,7 +6,7 @@ pub fn Switch(props: SwitchProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } switch::Switch { - class: "switch", + class: "dx-switch", checked: props.checked, default_checked: props.default_checked, disabled: props.disabled, @@ -23,6 +23,6 @@ pub fn Switch(props: SwitchProps) -> Element { #[component] pub fn SwitchThumb(props: SwitchThumbProps) -> Element { rsx! { - switch::SwitchThumb { class: "switch-thumb", attributes: props.attributes, {props.children} } + switch::SwitchThumb { class: "dx-switch-thumb", attributes: props.attributes, {props.children} } } } diff --git a/preview/src/components/switch/style.css b/preview/src/components/switch/style.css index f26e17d2..50da8a76 100644 --- a/preview/src/components/switch/style.css +++ b/preview/src/components/switch/style.css @@ -1,11 +1,11 @@ -.switch-example { +.dx-switch-example { display: flex; align-items: center; padding: 20px; gap: 15px; } -.switch { +.dx-switch { all: unset; position: relative; width: 2rem; @@ -16,11 +16,11 @@ transition: background-color 150ms; } -.switch[data-state="checked"] { +.dx-switch[data-state="checked"] { background-color: var(--secondary-color-2); } -.switch-thumb { +.dx-switch-thumb { display: block; width: calc(1.15rem - 2px); height: calc(1.15rem - 2px); @@ -31,13 +31,13 @@ will-change: transform; } -.switch[data-state="checked"] .switch-thumb { +.dx-switch[data-state="checked"] .dx-switch-thumb { background-color: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3)); transform: translateX(calc(2rem - 1px - (1.15rem - 2px))); } /* Only apply disabled styles when data-disabled is "true" */ -.switch[data-disabled="true"] { +.dx-switch[data-disabled="true"] { cursor: not-allowed; opacity: 0.5; } diff --git a/preview/src/components/tabs/component.rs b/preview/src/components/tabs/component.rs index 93ade03a..9ce563a8 100644 --- a/preview/src/components/tabs/component.rs +++ b/preview/src/components/tabs/component.rs @@ -68,7 +68,7 @@ pub fn Tabs(props: TabsProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } tabs::Tabs { - class: props.class + " tabs", + class: props.class + " dx-tabs", "data-variant": props.variant.to_class(), value: props.value, default_value: props.default_value, @@ -85,7 +85,7 @@ pub fn Tabs(props: TabsProps) -> Element { #[component] pub fn TabList(props: TabListProps) -> Element { rsx! { - tabs::TabList { class: "tabs-list", attributes: props.attributes, {props.children} } + tabs::TabList { class: "dx-tabs-list", attributes: props.attributes, {props.children} } } } @@ -93,7 +93,7 @@ pub fn TabList(props: TabListProps) -> Element { pub fn TabTrigger(props: TabTriggerProps) -> Element { rsx! { tabs::TabTrigger { - class: "tabs-trigger", + class: "dx-tabs-trigger", id: props.id, value: props.value, index: props.index, @@ -108,7 +108,7 @@ pub fn TabTrigger(props: TabTriggerProps) -> Element { pub fn TabContent(props: TabContentProps) -> Element { rsx! { tabs::TabContent { - class: props.class.unwrap_or_default() + " tabs-content tabs-content-themed", + class: props.class.unwrap_or_default() + " dx-tabs-content dx-tabs-content-themed", value: props.value, id: props.id, index: props.index, diff --git a/preview/src/components/tabs/style.css b/preview/src/components/tabs/style.css index 5e04cd01..30ee1aea 100644 --- a/preview/src/components/tabs/style.css +++ b/preview/src/components/tabs/style.css @@ -1,11 +1,11 @@ -.tabs { +.dx-tabs { display: flex; width: 100%; flex-direction: column; gap: 0.5rem; } -.tabs-list { +.dx-tabs-list { display: flex; width: fit-content; box-sizing: border-box; @@ -17,12 +17,12 @@ gap: 0.25rem; } -[data-variant="default"] .tabs-list { +[data-variant="default"] .dx-tabs-list { background: var(--light, var(--primary-color-3)) var(--dark, var(--primary-color-5)); } -.tabs-trigger { +.dx-tabs-trigger { padding: 4px 8px; border: none; border-radius: calc(0.5rem - 0.25rem); @@ -31,34 +31,34 @@ cursor: pointer; } -[data-variant="default"] .tabs-trigger[data-state="active"] { +[data-variant="default"] .dx-tabs-trigger[data-state="active"] { background-color: var(--light, var(--primary-color)) var(--dark, var(--primary-color-6)); box-shadow: var(--dark, inset 0 0 0 1px var(--primary-color-7)) var(--light, 0 1px 2px rgb(0 0 0 / 18%)); } -.tabs-trigger[data-state="active"] { +.dx-tabs-trigger[data-state="active"] { color: var(--secondary-color-1); } -.tabs-trigger[data-disabled="true"] { +.dx-tabs-trigger[data-disabled="true"] { color: var(--secondary-color-5); cursor: not-allowed; } -.tabs-trigger:hover:not([data-disabled="true"]), -.tabs-trigger:focus-visible { +.dx-tabs-trigger:hover:not([data-disabled="true"]), +.dx-tabs-trigger:focus-visible { color: var(--secondary-color-3); } -.tabs-content { +.dx-tabs-content { width: 100%; box-sizing: border-box; padding: 0.25rem; } -[data-variant="default"] .tabs-content-themed { +[data-variant="default"] .dx-tabs-content-themed { border: 1px solid var(--light, var(--primary-color-6)) var(--dark, var(--primary-color-7)); border-radius: 0.5rem; @@ -67,6 +67,6 @@ box-shadow: var(--light, 0 1px 2px rgb(0 0 0 / 18%)) var(--dark, none); } -.tabs-content[data-state="inactive"] { +.dx-tabs-content[data-state="inactive"] { display: none; } diff --git a/preview/src/components/textarea/component.rs b/preview/src/components/textarea/component.rs index 7f4db3cc..dab014ce 100644 --- a/preview/src/components/textarea/component.rs +++ b/preview/src/components/textarea/component.rs @@ -50,7 +50,7 @@ pub fn Textarea( rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } textarea { - class: "textarea", + class: "dx-textarea", "data-slot": "textarea", "data-style": variant.class(), oninput: move |e| _ = oninput.map(|callback| callback(e)), diff --git a/preview/src/components/textarea/style.css b/preview/src/components/textarea/style.css index 0a2c4998..e2fb4a7c 100644 --- a/preview/src/components/textarea/style.css +++ b/preview/src/components/textarea/style.css @@ -1,5 +1,5 @@ /* Base */ -.textarea { +.dx-textarea { width: 100%; min-height: 4rem; box-sizing: border-box; @@ -17,68 +17,68 @@ transition: background-color 100ms ease-out, border-color 100ms ease-out, box-shadow 100ms ease-out; } -.textarea:disabled { +.dx-textarea:disabled { color: var(--secondary-color-5); cursor: not-allowed; } -.textarea::placeholder { +.dx-textarea::placeholder { color: var(--secondary-color-5); } /* Default Variant */ -.textarea[data-style="default"] { +.dx-textarea[data-style="default"] { background: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3)); box-shadow: inset 0 0 0 1px var(--light, var(--primary-color-6)) var(--dark, var(--primary-color-7)); } -.textarea[data-style="default"]:hover:not(:disabled), -.textarea[data-style="default"]:focus { +.dx-textarea[data-style="default"]:hover:not(:disabled), +.dx-textarea[data-style="default"]:focus { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-5)); color: var(--secondary-color-1); } /* Fade Variant */ -.textarea[data-style="fade"] { +.dx-textarea[data-style="fade"] { background: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3)); } -.textarea[data-style="fade"]:hover:not(:disabled), -.textarea[data-style="fade"]:focus { +.dx-textarea[data-style="fade"]:hover:not(:disabled), +.dx-textarea[data-style="fade"]:focus { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-5)); color: var(--secondary-color-1); } /* Outline Variant */ -.textarea[data-style="outline"] { +.dx-textarea[data-style="outline"] { border: 1px solid var(--primary-color-6); background-color: var(--light, var(--primary-color)) var(--dark, var(--primary-color-3)); } -.textarea[data-style="outline"]:hover:not(:disabled, :focus) { +.dx-textarea[data-style="outline"]:hover:not(:disabled, :focus) { border-color: var(--primary-color-7); } -.textarea[data-style="outline"]:focus { +.dx-textarea[data-style="outline"]:focus { border-color: var(--focused-border-color); } -.textarea[data-style="outline"]:invalid, -.textarea[data-style="outline"][aria-invalid="true"] { +.dx-textarea[data-style="outline"]:invalid, +.dx-textarea[data-style="outline"][aria-invalid="true"] { border-color: var(--primary-error-color); } /* Ghost Variant */ -.textarea[data-style="ghost"] { +.dx-textarea[data-style="ghost"] { background-color: transparent; } -.textarea[data-style="ghost"]:hover:not(:disabled) { +.dx-textarea[data-style="ghost"]:hover:not(:disabled) { background-color: var(--primary-color-5); color: var(--secondary-color-1); } -.textarea[data-style="ghost"]:focus { +.dx-textarea[data-style="ghost"]:focus { border-color: var(--focused-border-color); } diff --git a/preview/src/components/toast/style.css b/preview/src/components/toast/style.css index 7bf994a1..e3816fa9 100644 --- a/preview/src/components/toast/style.css +++ b/preview/src/components/toast/style.css @@ -1,4 +1,4 @@ -.toast-container { +.dx-toast-container { position: fixed; z-index: 9999; right: 20px; @@ -6,7 +6,7 @@ max-width: 350px; } -.toast-list { +.dx-toast-list { display: flex; flex-direction: column-reverse; padding: 0; @@ -14,11 +14,11 @@ gap: 0.75rem; } -.toast-item { +.dx-toast-item { display: flex; } -.toast { +.dx-toast { z-index: calc(var(--toast-count) - var(--toast-index)); display: flex; overflow: hidden; @@ -48,17 +48,17 @@ --toast-hidden: calc(min(max(0, var(--toast-index) - 2), 1)); } -.toast-container:not(:hover, :focus-within) - .toast[data-toast-even]:not([data-top]) { - animation: slide-up-even 0.2s ease-out; +.dx-toast-container:not(:hover, :focus-within) + .dx-toast[data-toast-even]:not([data-top]) { + animation: dx-slide-up-even 0.2s ease-out; } -.toast-container:not(:hover, :focus-within) - .toast[data-toast-odd]:not([data-top]) { - animation: slide-up-odd 0.2s ease-out; +.dx-toast-container:not(:hover, :focus-within) + .dx-toast[data-toast-odd]:not([data-top]) { + animation: dx-slide-up-odd 0.2s ease-out; } -@keyframes slide-up-even { +@keyframes dx-slide-up-even { from { transform: translateY(0.5rem) scale( @@ -76,7 +76,7 @@ } } -@keyframes slide-up-odd { +@keyframes dx-slide-up-odd { from { transform: translateY(0.5rem) scale( @@ -94,16 +94,16 @@ } } -.toast[data-top] { - animation: slide-in 0.2s ease-out; +.dx-toast[data-top] { + animation: dx-toast-slide-in 0.2s ease-out; } -.toast-container:hover .toast[data-top], -.toast-container:focus-within .toast[data-top] { - animation: slide-in 0 ease-out; +.dx-toast-container:hover .dx-toast[data-top], +.dx-toast-container:focus-within .dx-toast[data-top] { + animation: dx-toast-slide-in 0 ease-out; } -@keyframes slide-in { +@keyframes dx-toast-slide-in { from { opacity: 0; transform: translateY(100%) @@ -123,52 +123,52 @@ } } -.toast-container:hover .toast, -.toast-container:focus-within .toast { +.dx-toast-container:hover .dx-toast, +.dx-toast-container:focus-within .dx-toast { margin-top: var(--toast-padding); filter: brightness(1); opacity: 1; transform: scale(calc(100%)); } -.toast[data-type="success"] { +.dx-toast[data-type="success"] { background-color: var(--primary-success-color); color: var(--secondary-success-color); } -.toast[data-type="error"] { +.dx-toast[data-type="error"] { background-color: var(--primary-error-color); color: var(--contrast-error-color); } -.toast[data-type="warning"] { +.dx-toast[data-type="warning"] { background-color: var(--primary-warning-color); color: var(--secondary-warning-color); } -.toast[data-type="info"] { +.dx-toast[data-type="info"] { background-color: var(--primary-info-color); color: var(--secondary-info-color); } -.toast-content { +.dx-toast-content { flex: 1; margin-right: 8px; transition: filter 0.2s ease; } -.toast-title { +.dx-toast-title { margin-bottom: 4px; color: var(--secondary-color-4); font-weight: 600; } -.toast-description { +.dx-toast-description { color: var(--secondary-color-3); font-size: 0.875rem; } -.toast-close { +.dx-toast-close { align-self: flex-start; padding: 0; border: none; @@ -180,6 +180,6 @@ line-height: 1; } -.toast-close:hover { +.dx-toast-close:hover { color: var(--secondary-color-1); } diff --git a/preview/src/components/toggle/component.rs b/preview/src/components/toggle/component.rs index 7a7ae261..a43da8c5 100644 --- a/preview/src/components/toggle/component.rs +++ b/preview/src/components/toggle/component.rs @@ -6,7 +6,7 @@ pub fn Toggle(props: ToggleProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } toggle::Toggle { - class: "toggle", + class: "dx-toggle", pressed: props.pressed, default_pressed: props.default_pressed, disabled: props.disabled, diff --git a/preview/src/components/toggle/style.css b/preview/src/components/toggle/style.css index f62da09c..1d14da61 100644 --- a/preview/src/components/toggle/style.css +++ b/preview/src/components/toggle/style.css @@ -1,4 +1,4 @@ -.toggle { +.dx-toggle { display: inline-flex; width: fit-content; min-width: 2rem; @@ -15,12 +15,12 @@ outline: none; } -.toggle:hover, .toggle:focus-visible { +.dx-toggle:hover, .dx-toggle:focus-visible { background-color: var(--primary-color-4); cursor: pointer; } -.toggle[data-state="on"] { +.dx-toggle[data-state="on"] { background-color: var(--primary-color-7); color: var(--secondary-color-1); } diff --git a/preview/src/components/toggle_group/component.rs b/preview/src/components/toggle_group/component.rs index b8f8e772..8fad7fb2 100644 --- a/preview/src/components/toggle_group/component.rs +++ b/preview/src/components/toggle_group/component.rs @@ -6,7 +6,7 @@ pub fn ToggleGroup(props: ToggleGroupProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } toggle_group::ToggleGroup { - class: "toggle-group", + class: "dx-toggle-group", default_pressed: props.default_pressed, pressed: props.pressed, on_pressed_change: props.on_pressed_change, @@ -24,7 +24,7 @@ pub fn ToggleGroup(props: ToggleGroupProps) -> Element { pub fn ToggleItem(props: ToggleItemProps) -> Element { rsx! { toggle_group::ToggleItem { - class: "toggle-item", + class: "dx-toggle-item", index: props.index, disabled: props.disabled, attributes: props.attributes, diff --git a/preview/src/components/toggle_group/style.css b/preview/src/components/toggle_group/style.css index e9e24056..d40f2c6c 100644 --- a/preview/src/components/toggle_group/style.css +++ b/preview/src/components/toggle_group/style.css @@ -1,8 +1,8 @@ -.toggle-group { +.dx-toggle-group { width: fit-content; } -.toggle-item { +.dx-toggle-item { min-width: 35px; padding: 10px; border: none; @@ -14,46 +14,46 @@ transition: background-color 200ms ease, border 200ms ease; } -.toggle-group[data-allow-multiple-pressed="true"] - .toggle-item { +.dx-toggle-group[data-allow-multiple-pressed="true"] + .dx-toggle-item { border-top: 1px solid var(--primary-color-6); border-right: 1px solid var(--primary-color-6); border-bottom: 1px solid var(--primary-color-6); } -.toggle-item:hover, -.toggle-item:focus-visible { +.dx-toggle-item:hover, +.dx-toggle-item:focus-visible { background-color: var(--primary-color-4); cursor: pointer; } -.toggle-item[data-state="on"] { +.dx-toggle-item[data-state="on"] { background-color: var(--primary-color-7); color: var(--secondary-color-1); } -.toggle-group[data-allow-multiple-pressed="true"] - .toggle-item[data-state="on"] { +.dx-toggle-group[data-allow-multiple-pressed="true"] + .dx-toggle-item[data-state="on"] { border-top: 1px solid var(--secondary-color-6); border-right: 1px solid var(--secondary-color-6); border-bottom: 1px solid var(--secondary-color-6); } -.toggle-group[data-allow-multiple-pressed="true"] - .toggle-item:first-child[data-state="on"] { +.dx-toggle-group[data-allow-multiple-pressed="true"] + .dx-toggle-item:first-child[data-state="on"] { border: 1px solid var(--secondary-color-6); } -.toggle-item:first-child { +.dx-toggle-item:first-child { border-bottom-left-radius: 0.5rem; border-top-left-radius: 0.5rem; } -.toggle-group[data-allow-multiple-pressed="true"] .toggle-item:first-child { +.dx-toggle-group[data-allow-multiple-pressed="true"] .dx-toggle-item:first-child { border: 1px solid var(--primary-color-6); } -.toggle-item:last-child { +.dx-toggle-item:last-child { border-bottom-right-radius: 0.5rem; border-top-right-radius: 0.5rem; } diff --git a/preview/src/components/toolbar/component.rs b/preview/src/components/toolbar/component.rs index 0d823ee3..31771b17 100644 --- a/preview/src/components/toolbar/component.rs +++ b/preview/src/components/toolbar/component.rs @@ -6,7 +6,7 @@ pub fn Toolbar(props: ToolbarProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } toolbar::Toolbar { - class: "toolbar", + class: "dx-toolbar", aria_label: props.aria_label, disabled: props.disabled, horizontal: props.horizontal, @@ -20,7 +20,7 @@ pub fn Toolbar(props: ToolbarProps) -> Element { pub fn ToolbarButton(props: ToolbarButtonProps) -> Element { rsx! { toolbar::ToolbarButton { - class: "toolbar-button", + class: "dx-toolbar-button", index: props.index, disabled: props.disabled, on_click: props.on_click, @@ -34,7 +34,7 @@ pub fn ToolbarButton(props: ToolbarButtonProps) -> Element { pub fn ToolbarSeparator(props: ToolbarSeparatorProps) -> Element { rsx! { toolbar::ToolbarSeparator { - class: "toolbar-separator", + class: "dx-toolbar-separator", decorative: props.decorative, horizontal: props.horizontal, attributes: props.attributes, @@ -50,6 +50,6 @@ pub fn ToolbarGroup( children: Element, ) -> Element { rsx! { - div { class: "toolbar-group", ..attributes, {children} } + div { class: "dx-toolbar-group", ..attributes, {children} } } } diff --git a/preview/src/components/toolbar/style.css b/preview/src/components/toolbar/style.css index 75513efe..16e628e8 100644 --- a/preview/src/components/toolbar/style.css +++ b/preview/src/components/toolbar/style.css @@ -1,4 +1,4 @@ -.toolbar { +.dx-toolbar { display: flex; flex-flow: row wrap; align-items: center; @@ -10,7 +10,7 @@ gap: .25rem; } -.toolbar button { +.dx-toolbar button { padding: 8px 12px; border: none; border-radius: calc(.5rem - .25rem); @@ -19,32 +19,32 @@ cursor: pointer; } -.toolbar button:hover:not([disabled]), -.toolbar button:focus-visible { +.dx-toolbar button:hover:not([disabled]), +.dx-toolbar button:focus-visible { background: var(--light, var(--primary-color-4)) var(--dark, var(--primary-color-7)); color: var(--secondary-color-1); } -.toolbar button:disabled { +.dx-toolbar button:disabled { color: var(--secondary-color-5); cursor: not-allowed; } -.toolbar-group { +.dx-toolbar-group { display: flex; flex-direction: row; gap: 5px; } -.toolbar-separator { +.dx-toolbar-separator { width: 1px; height: 24px; margin: 0 5px; background-color: var(--primary-color-6); } -.toolbar-content p { +.dx-toolbar-content p { padding: 0; margin: 0; } diff --git a/preview/src/components/tooltip/component.rs b/preview/src/components/tooltip/component.rs index ea48bc4b..7663339d 100644 --- a/preview/src/components/tooltip/component.rs +++ b/preview/src/components/tooltip/component.rs @@ -6,7 +6,7 @@ pub fn Tooltip(props: TooltipProps) -> Element { rsx! { document::Link { rel: "stylesheet", href: asset!("./style.css") } tooltip::Tooltip { - class: "tooltip", + class: "dx-tooltip", disabled: props.disabled, open: props.open, default_open: props.default_open, @@ -21,7 +21,7 @@ pub fn Tooltip(props: TooltipProps) -> Element { pub fn TooltipTrigger(props: TooltipTriggerProps) -> Element { rsx! { tooltip::TooltipTrigger { - class: "tooltip-trigger", + class: "dx-tooltip-trigger", id: props.id, as: props.r#as, attributes: props.attributes, @@ -34,7 +34,7 @@ pub fn TooltipTrigger(props: TooltipTriggerProps) -> Element { pub fn TooltipContent(props: TooltipContentProps) -> Element { rsx! { tooltip::TooltipContent { - class: "tooltip-content", + class: "dx-tooltip-content", id: props.id, side: props.side, align: props.align, diff --git a/preview/src/components/tooltip/style.css b/preview/src/components/tooltip/style.css index 0388ab83..857b87af 100644 --- a/preview/src/components/tooltip/style.css +++ b/preview/src/components/tooltip/style.css @@ -1,27 +1,27 @@ /* Tooltip Styles */ -.tooltip { +.dx-tooltip { position: relative; display: inline-block; } -.tooltip-trigger { +.dx-tooltip-trigger { display: inline-block; } -.tooltip-content { +.dx-tooltip-content { position: absolute; z-index: 1000; max-width: 250px; padding: 8px 12px; border-radius: 0.5rem; - animation: tooltip-fade-in 0.2s ease-in-out; + animation: dx-tooltip-fade-in 0.2s ease-in-out; background-color: var(--secondary-color-4); color: var(--primary-color); font-size: 14px; line-height: 1.4; } -.tooltip-content::after { +.dx-tooltip-content::after { position: absolute; border-width: 0.25rem; border-style: solid; @@ -31,7 +31,7 @@ } /* Positioning based on side */ -.tooltip-content[data-side="top"] { +.dx-tooltip-content[data-side="top"] { position: absolute; bottom: 100%; left: 50%; @@ -39,14 +39,14 @@ transform: translateX(-50%); } -.tooltip-content[data-side="top"]::after { +.dx-tooltip-content[data-side="top"]::after { top: calc(100% - 0.25rem); left: 50%; border-color: var(--secondary-color-4); border-radius: 0 0 0.1rem; } -.tooltip-content[data-side="right"] { +.dx-tooltip-content[data-side="right"] { position: absolute; top: 50%; left: 100%; @@ -54,14 +54,14 @@ transform: translateY(-50%); } -.tooltip-content[data-side="right"]::after { +.dx-tooltip-content[data-side="right"]::after { top: calc(50% - 0.25rem); left: 0; border-color: var(--secondary-color-4); border-radius: 0 0 0 0.1rem; } -.tooltip-content[data-side="bottom"] { +.dx-tooltip-content[data-side="bottom"] { position: absolute; top: 100%; left: 50%; @@ -69,14 +69,14 @@ transform: translateX(-50%); } -.tooltip-content[data-side="bottom"]::after { +.dx-tooltip-content[data-side="bottom"]::after { bottom: calc(100% - 0.25rem); left: 50%; border-color: var(--secondary-color-4); border-radius: 0.1rem 0 0; } -.tooltip-content[data-side="left"] { +.dx-tooltip-content[data-side="left"] { position: absolute; top: 50%; right: 100%; @@ -84,7 +84,7 @@ transform: translateY(-50%); } -.tooltip-content[data-side="left"]::after { +.dx-tooltip-content[data-side="left"]::after { top: calc(50% - 0.25rem); right: -0.25rem; border-color: var(--secondary-color-4); @@ -92,41 +92,41 @@ } /* Alignment styles for top and bottom */ -.tooltip-content[data-side="top"][data-align="start"], -.tooltip-content[data-side="bottom"][data-align="start"] { +.dx-tooltip-content[data-side="top"][data-align="start"], +.dx-tooltip-content[data-side="bottom"][data-align="start"] { left: 0; transform: none; } -.tooltip-content[data-side="top"][data-align="end"], -.tooltip-content[data-side="bottom"][data-align="end"] { +.dx-tooltip-content[data-side="top"][data-align="end"], +.dx-tooltip-content[data-side="bottom"][data-align="end"] { right: 0; left: auto; transform: none; } /* Alignment styles for left and right */ -.tooltip-content[data-side="left"][data-align="start"], -.tooltip-content[data-side="right"][data-align="start"] { +.dx-tooltip-content[data-side="left"][data-align="start"], +.dx-tooltip-content[data-side="right"][data-align="start"] { top: 0; transform: none; } -.tooltip-content[data-side="left"][data-align="center"], -.tooltip-content[data-side="right"][data-align="center"] { +.dx-tooltip-content[data-side="left"][data-align="center"], +.dx-tooltip-content[data-side="right"][data-align="center"] { top: 50%; transform: translateY(-50%); } -.tooltip-content[data-side="left"][data-align="end"], -.tooltip-content[data-side="right"][data-align="end"] { +.dx-tooltip-content[data-side="left"][data-align="end"], +.dx-tooltip-content[data-side="right"][data-align="end"] { top: auto; bottom: 0; transform: none; } /* Animation */ -@keyframes tooltip-fade-in { +@keyframes dx-tooltip-fade-in { from { opacity: 0; } @@ -137,14 +137,14 @@ } /* State styles */ -.tooltip[data-disabled="true"] .tooltip-trigger { +.dx-tooltip[data-disabled="true"] .dx-tooltip-trigger { cursor: default; } -.tooltip-content[data-state="closed"] { +.dx-tooltip-content[data-state="closed"] { display: none; } -.tooltip-content[data-state="open"] { +.dx-tooltip-content[data-state="open"] { display: block; }