@qeetrix/react 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +116 -1
- package/README.md +99 -0
- package/dist/button/button.d.ts +6 -2
- package/dist/button/button.js +5 -1
- package/dist/css/avatar.css +6 -0
- package/dist/css/badge.css +6 -0
- package/dist/css/button.css +81 -6
- package/dist/css/checkbox.css +9 -0
- package/dist/css/dialog.css +7 -0
- package/dist/css/drawer.css +6 -0
- package/dist/css/experimental/alert.css +89 -0
- package/dist/css/experimental/app-shell.css +258 -0
- package/dist/css/experimental/breadcrumb.css +67 -0
- package/dist/css/experimental/copy-button.css +13 -0
- package/dist/css/experimental/empty-state.css +63 -0
- package/dist/css/experimental/otp-input.css +84 -0
- package/dist/css/experimental/page-header.css +110 -0
- package/dist/css/experimental/password-input.css +21 -0
- package/dist/css/experimental/sidebar.css +234 -0
- package/dist/css/experimental/stat.css +115 -0
- package/dist/css/experimental/top-bar.css +299 -0
- package/dist/css/input.css +10 -0
- package/dist/css/menu.css +17 -0
- package/dist/css/progress.css +14 -0
- package/dist/css/scroll-area.css +7 -0
- package/dist/css/select.css +16 -0
- package/dist/css/separator.css +7 -0
- package/dist/css/skeleton.css +6 -0
- package/dist/css/slider.css +22 -0
- package/dist/css/switch.css +33 -0
- package/dist/css/tabs.css +11 -0
- package/dist/css/toast.css +7 -0
- package/dist/css/toggle.css +13 -0
- package/dist/css/tooltip.css +6 -0
- package/dist/dialog/dialog.d.ts +4 -1
- package/dist/dialog/dialog.js +4 -3
- package/dist/drawer/drawer.d.ts +4 -1
- package/dist/drawer/drawer.js +5 -4
- package/dist/experimental/alert/alert.d.ts +29 -0
- package/dist/experimental/alert/alert.js +72 -0
- package/dist/experimental/alert/index.d.ts +2 -0
- package/dist/experimental/app-shell/app-shell.d.ts +60 -0
- package/dist/experimental/app-shell/app-shell.js +224 -0
- package/dist/experimental/app-shell/index.d.ts +2 -0
- package/dist/experimental/breadcrumb/breadcrumb.d.ts +27 -0
- package/dist/experimental/breadcrumb/breadcrumb.js +48 -0
- package/dist/experimental/breadcrumb/index.d.ts +2 -0
- package/dist/experimental/copy-button/copy-button.d.ts +27 -0
- package/dist/experimental/copy-button/copy-button.js +61 -0
- package/dist/experimental/copy-button/index.d.ts +2 -0
- package/dist/experimental/empty-state/data-state.d.ts +23 -0
- package/dist/experimental/empty-state/data-state.js +40 -0
- package/dist/experimental/empty-state/empty-state.d.ts +26 -0
- package/dist/experimental/empty-state/empty-state.js +46 -0
- package/dist/experimental/empty-state/index.d.ts +3 -0
- package/dist/experimental/index.d.ts +24 -0
- package/dist/experimental/index.js +13 -0
- package/dist/experimental/otp-input/index.d.ts +2 -0
- package/dist/experimental/otp-input/otp-input.d.ts +27 -0
- package/dist/experimental/otp-input/otp-input.js +39 -0
- package/dist/experimental/page-header/index.d.ts +2 -0
- package/dist/experimental/page-header/page-header.d.ts +32 -0
- package/dist/experimental/page-header/page-header.js +73 -0
- package/dist/experimental/password-input/index.d.ts +2 -0
- package/dist/experimental/password-input/password-input.d.ts +26 -0
- package/dist/experimental/password-input/password-input.js +103 -0
- package/dist/experimental/sidebar/index.d.ts +2 -0
- package/dist/experimental/sidebar/sidebar.d.ts +64 -0
- package/dist/experimental/sidebar/sidebar.js +200 -0
- package/dist/experimental/stat/index.d.ts +2 -0
- package/dist/experimental/stat/stat.d.ts +31 -0
- package/dist/experimental/stat/stat.js +90 -0
- package/dist/experimental/top-bar/index.d.ts +2 -0
- package/dist/experimental/top-bar/top-bar.d.ts +60 -0
- package/dist/experimental/top-bar/top-bar.js +162 -0
- package/dist/field/field.d.ts +4 -1
- package/dist/field/field.js +6 -5
- package/dist/format/format.d.ts +12 -0
- package/dist/format/format.js +50 -0
- package/dist/format/index.d.ts +2 -0
- package/dist/format/index.js +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +3 -1
- package/dist/internal/media.js +15 -0
- package/dist/internal/messages.d.ts +75 -0
- package/dist/internal/messages.js +44 -5
- package/dist/link/link.d.ts +7 -1
- package/dist/link/link.js +3 -2
- package/dist/locales/hi.d.ts +8 -0
- package/dist/locales/hi.js +60 -0
- package/dist/progress/progress.d.ts +2 -2
- package/dist/progress/progress.js +7 -2
- package/dist/provider/index.d.ts +3 -0
- package/dist/provider/index.js +1 -0
- package/dist/provider/provider.d.ts +46 -0
- package/dist/provider/provider.js +90 -0
- package/dist/slider/slider.d.ts +5 -2
- package/dist/slider/slider.js +10 -3
- package/dist/styles.css +1704 -104
- package/dist/text-field/text-field.d.ts +2 -2
- package/dist/text-field/text-field.js +4 -2
- package/dist/toast/toast.d.ts +4 -1
- package/dist/toast/toast.js +7 -6
- package/package.json +18 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,89 @@
|
|
|
1
1
|
# @qeetrix/react
|
|
2
2
|
|
|
3
|
+
## 0.0.3
|
|
4
|
+
|
|
5
|
+
The first two Phase 5 increments, from `@qeetrix/react/experimental`: C1, the console frame, and
|
|
6
|
+
C2, secure entry. Experimental parts may change in a patch release; each moves to the root export
|
|
7
|
+
once it has shipped in its product (07-components.md).
|
|
8
|
+
|
|
9
|
+
### C1 · Console frame
|
|
10
|
+
|
|
11
|
+
- **`AppShell`** (design B · Ruled, chosen from three researched concepts; 07-components.md):
|
|
12
|
+
- the frame of every Qeet console: a skip link, the sticky TopBar across the full width, the
|
|
13
|
+
navigation column on the canvas tone, the page, and an end-edge panel; every seam a 1px rule;
|
|
14
|
+
- from 840px the navigation collapses to a 48px rail (`sidebarCollapsed` /
|
|
15
|
+
`defaultSidebarCollapsed` / `onSidebarCollapsedChange`) that expands over the page while hovered
|
|
16
|
+
or focused; below 840px it opens as a drawer from the start edge;
|
|
17
|
+
- `drawers` (help, assistant, activity), opened from the TopBar's tools: one at a time, pushing
|
|
18
|
+
the page from 1200px; `notifications` above the page; `density`, compact by default;
|
|
19
|
+
- `useAppShell()` tells content inside the frame when the sidebar is a rail.
|
|
20
|
+
- **`TopBar`, `TopBarSwitcher`, `TopBarSearch`:**
|
|
21
|
+
- black in light and dark (the dark scheme on itself), topped by a 2px Ember line;
|
|
22
|
+
- product to global, left to right: launcher cell, product, the scope path with drawn slashes,
|
|
23
|
+
centred search, panel triggers and utilities, account;
|
|
24
|
+
- `TopBarSwitcher` is a step of the path (organisation mark, environment status dot, always a
|
|
25
|
+
word) and works as a Menu trigger; `TopBarSearch` is a field-shaped button with its shortcut.
|
|
26
|
+
- **`PageHeader`, `PageContent`:** breadcrumb, `title.lg` title with count and status, actions, a
|
|
27
|
+
`summary` strip bled to the page edges, and tabs at the foot; a 32px page gutter.
|
|
28
|
+
- **`Stat`, `StatGroup`:** key numbers in ruled cells; numeric values formatted for the locale; an
|
|
29
|
+
optional decorative trend line whose last point is the Ember mark. Server-safe.
|
|
30
|
+
- **`Sidebar`, `SidebarGroup`, `SidebarItem`:**
|
|
31
|
+
- links only, one level of nesting, every item in the Tab order;
|
|
32
|
+
- square rows edge to edge with round icons; the current page gets `aria-current`, the 3px Ember
|
|
33
|
+
bar, weight 600 and an Ember (optionally filled) icon;
|
|
34
|
+
- groups between hairlines under tracked small capitals (`typography.label.caps`; untracked for
|
|
35
|
+
Indic text, which has no case); an optional `title`, `filter` and `footer`;
|
|
36
|
+
- in the rail, icons stay where they are and labels become tooltips.
|
|
37
|
+
- **`Breadcrumb`, `BreadcrumbItem`:** server-safe; mirrored chevrons; long labels truncate and keep a
|
|
38
|
+
title.
|
|
39
|
+
- **`EmptyState`:** a 24px icon, a title (a heading when given a `level`), a description and actions,
|
|
40
|
+
in `page` or `section` size and `neutral` or `danger` tone. Server-safe.
|
|
41
|
+
- **`DataState`:** loading, then error, then empty, then the content. The error state never shows the
|
|
42
|
+
raw error, and `onRetry` adds "Try again".
|
|
43
|
+
- **Colour scheme:**
|
|
44
|
+
- `QeetrixProvider` takes `colorScheme`, `defaultColorScheme` and `onColorSchemeChange`, writes
|
|
45
|
+
`data-qx-color-scheme` on `<html>`, and follows the operating system while `system`;
|
|
46
|
+
- `useColorScheme()` returns the scheme and a setter. The product persists the choice.
|
|
47
|
+
- **`Button` and `IconButton`:**
|
|
48
|
+
- a `neutral` tone for ghost utility actions in toolbars and headers, whose icons stay neutral
|
|
49
|
+
(design rules §16);
|
|
50
|
+
- a Button's icon sits in its own zone (the new `button-zone` slot), behind a 1px rule as tall as
|
|
51
|
+
the icon, in the label's colour (design rules §7).
|
|
52
|
+
- **Strings:** new `appShell`, `sidebar`, `breadcrumb` and `dataState` groups, in English and Hindi.
|
|
53
|
+
- **Peer dependency:** `@qeetrix/tokens` `^0.0.7`, for `typography.label.caps`. Since tokens 0.0.6
|
|
54
|
+
the stylesheet also loads Qeet Sans and Fira Code, so the tests now render in the real typefaces.
|
|
55
|
+
- **Source check:** every `var(--qx-*)` must name a token in the installed `@qeetrix/tokens` or a
|
|
56
|
+
property the package declares itself, so a token from a newer tokens release can't ship
|
|
57
|
+
unresolved.
|
|
58
|
+
- **Platform:**
|
|
59
|
+
- the CSS build, the dist check and the screenshot coverage test understand
|
|
60
|
+
`src/experimental/<family>/`;
|
|
61
|
+
- the test helper treats cancelled animations as settled.
|
|
62
|
+
|
|
63
|
+
### C2 · Secure entry
|
|
64
|
+
|
|
65
|
+
- **`CopyButton`:** copies a value (or what a function returns, even asynchronously); the icon
|
|
66
|
+
turns into a check, "Copied" is announced politely, focus stays, and it resets after 2 seconds.
|
|
67
|
+
It fails visibly where there's no clipboard. An IconButton named by `label`, or a Button with a
|
|
68
|
+
visible label.
|
|
69
|
+
- **`Alert`:** `info`, `success`, `warning` or `danger` on the status tint with the 3px status edge;
|
|
70
|
+
a title (led by a hidden tone word), a description, actions and an optional Dismiss. `announce`
|
|
71
|
+
makes it `role="status"` or `role="alert"` only when it appears after something happens. It never
|
|
72
|
+
takes focus or disappears by itself.
|
|
73
|
+
- **`PasswordInput`:** an Input with a pressed-state Show password toggle, announced; hidden by
|
|
74
|
+
default and hidden again when its form submits; `current-password` / `new-password` / `off`;
|
|
75
|
+
spelling and capitalisation tools off; a Caps Lock warning; `endAdornment` for a CopyButton.
|
|
76
|
+
- **`OTPInput`:** one-time codes in slots on Base UI's OTP Field: typing moves on, paste fills
|
|
77
|
+
every slot, SMS autofill lands at once; numeric by default; `groups`, `md` and `lg` sizes; the
|
|
78
|
+
first slot takes the field's label, the rest are "Character 2 of 6".
|
|
79
|
+
- **Strings:** new `copyButton`, `alert`, `passwordInput` and `otpInput` groups, in English and
|
|
80
|
+
Hindi.
|
|
81
|
+
|
|
3
82
|
## 0.0.2
|
|
4
83
|
|
|
5
84
|
Every primitive, in six increments: the foundation, actions, form controls, overlays, selection and
|
|
6
|
-
disclosure, and display and status.
|
|
85
|
+
disclosure, and display and status. Then the Phase 4 close-out: localisation, forced colours,
|
|
86
|
+
right-to-left, reduced motion and the sign-in exit screen.
|
|
7
87
|
|
|
8
88
|
### Foundation
|
|
9
89
|
|
|
@@ -160,8 +240,43 @@ content part that assembles the portal, positioner and popup.
|
|
|
160
240
|
- **`Skeleton`:** `text`, `block` or `circle`. It pulses, holds still under reduced motion, and is
|
|
161
241
|
always hidden from assistive technology. Server-safe.
|
|
162
242
|
|
|
243
|
+
### Phase 4 close-out
|
|
244
|
+
|
|
245
|
+
- **`QeetrixProvider`:**
|
|
246
|
+
- `locale` (default `en-IN`) for formatting;
|
|
247
|
+
- `direction`, which wraps Base UI's DirectionProvider;
|
|
248
|
+
- `messages`, merged over the English defaults group by group.
|
|
249
|
+
- Nested providers inherit what they don't set. `useLocale()` reads the locale.
|
|
250
|
+
- **Strings:**
|
|
251
|
+
- every library string comes from one typed catalogue (`QeetrixMessages`);
|
|
252
|
+
- Field, TextField, DialogContent, DrawerContent, ToastProvider, Slider and Link take a `messages`
|
|
253
|
+
prop that wins over the provider;
|
|
254
|
+
- Link stays server-safe, so it takes its string per instance.
|
|
255
|
+
- **Locale packs:** Hindi (`@qeetrix/react/locales/hi`) is the first. It's a separate entry point,
|
|
256
|
+
typed as the complete catalogue, and uses Qeet ID's own Hindi words.
|
|
257
|
+
- **Formatting:** `formatNumber`, `formatCurrency` (lakh and crore grouping by default) and
|
|
258
|
+
`formatRelativeTime`. They're pure, server-safe and cache their formatters. Slider, Progress and
|
|
259
|
+
Meter format in the provider's locale.
|
|
260
|
+
- **Forced colours (Windows High Contrast):**
|
|
261
|
+
- surfaces that showed only a fill or a shadow get a system-colour edge;
|
|
262
|
+
- on states use `Highlight`: pressed Toggle, Switch, checked Checkbox, the Slider and Progress
|
|
263
|
+
fills, the Tabs bar, and highlighted Menu and Select items;
|
|
264
|
+
- separators and the tab list's base line stay visible.
|
|
265
|
+
- **Right-to-left:** tests cover arrow keys in Tabs, ToggleGroup, RadioGroup, Slider and the Menu
|
|
266
|
+
submenu, plus the Drawer edge, the Menu bar side and the Input adornment order.
|
|
267
|
+
- **Reduced motion:** a test checks that durations collapse and that Spinner and indeterminate
|
|
268
|
+
Progress fade instead.
|
|
269
|
+
- **Slider:** a slider named by `aria-label` (no visible label) now passes the name on to its
|
|
270
|
+
thumbs, which are what carry the slider role. A range adds Minimum and Maximum.
|
|
271
|
+
- **Sign-in exit screen:** built from primitives alone. Its keyboard order, axe, and its light,
|
|
272
|
+
dark, right-to-left and forced-colours screenshots are all tested.
|
|
273
|
+
|
|
163
274
|
### Platform
|
|
164
275
|
|
|
276
|
+
- **Source check:**
|
|
277
|
+
- it bans physical CSS properties and system colours outside forced-colours blocks;
|
|
278
|
+
- it ignores comments when looking for client-only code.
|
|
279
|
+
|
|
165
280
|
- Each family's stylesheet (`css/<family>.css`) now imports the base layer and the stylesheets of
|
|
166
281
|
the families it renders, so it works on its own.
|
|
167
282
|
- Screenshots wait for transitions to finish, and overlays are captured across the whole viewport.
|
package/README.md
CHANGED
|
@@ -127,6 +127,105 @@ import { Checkbox, CheckboxGroup, Fieldset, Radio, RadioGroup, TextField } from
|
|
|
127
127
|
</Fieldset>
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
+
## Locale, direction and strings
|
|
131
|
+
|
|
132
|
+
Wrap the app in `QeetrixProvider` to set the locale (used for formatting), the reading direction and
|
|
133
|
+
the library's own strings ("Close", "(optional)", "Loading"…). Locale packs are separate imports, so
|
|
134
|
+
a language you don't use never ships:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { QeetrixProvider } from "@qeetrix/react";
|
|
138
|
+
import { hi } from "@qeetrix/react/locales/hi";
|
|
139
|
+
|
|
140
|
+
<QeetrixProvider locale="hi-IN" messages={hi}>{app}</QeetrixProvider>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
- **Override one string:** pass a `messages` prop to the component, e.g.
|
|
144
|
+
`<Field messages={{ optional: "(if any)" }}>`.
|
|
145
|
+
- **Right-to-left:** use `direction="rtl"`, and set `dir="rtl"` on `<html>` too.
|
|
146
|
+
- **Server-safe components** (Link, Spinner, SkipLink) can't read the provider. Pass their strings
|
|
147
|
+
per instance.
|
|
148
|
+
|
|
149
|
+
Formatting helpers are plain functions and work on the server too:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { formatCurrency, formatNumber, formatRelativeTime } from "@qeetrix/react";
|
|
153
|
+
|
|
154
|
+
formatCurrency(124500, "INR"); // "₹1,24,500.00"
|
|
155
|
+
formatNumber(1234567); // "12,34,567"
|
|
156
|
+
formatRelativeTime(updatedAt, "en-IN", now); // "2 minutes ago"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Every primitive also works in Windows High Contrast (forced colours) and under reduced motion. Tests
|
|
160
|
+
emulate both.
|
|
161
|
+
|
|
162
|
+
## Experimental: the console frame
|
|
163
|
+
|
|
164
|
+
Components and patterns in their first product ship from `@qeetrix/react/experimental`. They may
|
|
165
|
+
change in a patch release until they're Ready.
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
import {
|
|
169
|
+
AppShell, PageContent, PageHeader, Sidebar, SidebarGroup, SidebarItem, Stat, StatGroup,
|
|
170
|
+
TopBar, TopBarSearch, TopBarSwitcher,
|
|
171
|
+
} from "@qeetrix/react/experimental";
|
|
172
|
+
import { Menu, MenuContent, MenuItem, MenuTrigger } from "@qeetrix/react";
|
|
173
|
+
|
|
174
|
+
<AppShell
|
|
175
|
+
topBar={
|
|
176
|
+
<TopBar
|
|
177
|
+
logo={<QeetLogo variant="dark" height={20} />}
|
|
178
|
+
product="Qeet ID"
|
|
179
|
+
context={
|
|
180
|
+
<>
|
|
181
|
+
<Menu>
|
|
182
|
+
<MenuTrigger render={<TopBarSwitcher mark="AC" label="Acme Pvt Ltd" />} />
|
|
183
|
+
<MenuContent>{organisations}</MenuContent>
|
|
184
|
+
</Menu>
|
|
185
|
+
<TopBarSwitcher status="success" label="Production" />
|
|
186
|
+
</>
|
|
187
|
+
}
|
|
188
|
+
search={<TopBarSearch placeholder="Search or jump to…" shortcut={["⌘", "K"]} onClick={openPalette} />}
|
|
189
|
+
account={accountMenu}
|
|
190
|
+
/>
|
|
191
|
+
}
|
|
192
|
+
sidebar={
|
|
193
|
+
<Sidebar label="Qeet ID">
|
|
194
|
+
<SidebarGroup label="Directory">
|
|
195
|
+
<SidebarItem label="Users" icon={UsersIcon} current render={<Link to="/users" />} />
|
|
196
|
+
</SidebarGroup>
|
|
197
|
+
</Sidebar>
|
|
198
|
+
}
|
|
199
|
+
drawers={[{ id: "help", label: "Help", icon: CircleQuestionMarkIcon, content: help }]}
|
|
200
|
+
>
|
|
201
|
+
<PageHeader
|
|
202
|
+
title="Users"
|
|
203
|
+
actions={<Button icon={PlusIcon}>Invite users</Button>}
|
|
204
|
+
summary={
|
|
205
|
+
<StatGroup>
|
|
206
|
+
<Stat label="Total users" value={1284} note="+38 this week" tone="positive" trend={weekly} />
|
|
207
|
+
</StatGroup>
|
|
208
|
+
}
|
|
209
|
+
/>
|
|
210
|
+
<PageContent>{table}</PageContent>
|
|
211
|
+
</AppShell>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The bar is black in light and dark, topped by a 2px Ember line; the navigation collapses to a 48px
|
|
215
|
+
rail that expands while hovered. Also there: `Breadcrumb`, `EmptyState` and `DataState` (loading,
|
|
216
|
+
error, empty, content), and the secure-entry parts:
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
<Alert tone="warning" title="Copy this client secret now">It can't be shown again.</Alert>
|
|
220
|
+
<Field label="Client secret">
|
|
221
|
+
<PasswordInput readOnly autoComplete="off" defaultValue={secret}
|
|
222
|
+
endAdornment={<CopyButton value={secret} label="Copy client secret" size="sm" />} />
|
|
223
|
+
</Field>
|
|
224
|
+
<Field label="Verification code"><OTPInput size="lg" onValueComplete={verify} /></Field>
|
|
225
|
+
```
|
|
226
|
+
Colour-scheme switching lives in `QeetrixProvider`
|
|
227
|
+
(`defaultColorScheme="system"`, `useColorScheme()`).
|
|
228
|
+
|
|
130
229
|
## Overlays
|
|
131
230
|
|
|
132
231
|
Overlays share one shape: a root that holds the state, a trigger that renders your control, and a
|
package/dist/button/button.d.ts
CHANGED
|
@@ -2,11 +2,15 @@ import { ControlSize, QeetrixIcon } from "../internal/control.js";
|
|
|
2
2
|
import { ComponentProps, ReactElement, ReactNode } from "react";
|
|
3
3
|
import { Button } from "@base-ui/react/button";
|
|
4
4
|
export type ButtonVariant = "solid" | "soft" | "ghost";
|
|
5
|
-
export type ButtonTone = "brand" | "danger";
|
|
5
|
+
export type ButtonTone = "brand" | "danger" | "neutral";
|
|
6
6
|
interface ButtonBaseProps extends Omit<ComponentProps<"button">, "children"> {
|
|
7
7
|
/** Emphasis: `solid` (primary, Ember), `soft` (secondary, graphite), `ghost` (tertiary). */
|
|
8
8
|
variant?: ButtonVariant;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* `danger` for the confirming action of a destructive flow. `neutral` for ghost utility actions
|
|
11
|
+
* in toolbars and headers, whose icons stay neutral (design rules §16); a solid or soft neutral
|
|
12
|
+
* button looks like the soft one.
|
|
13
|
+
*/
|
|
10
14
|
tone?: ButtonTone;
|
|
11
15
|
/** Height from the density tokens. Default `md`. */
|
|
12
16
|
size?: ControlSize;
|
package/dist/button/button.js
CHANGED
|
@@ -43,7 +43,11 @@ function Button$1({ variant = "solid", tone = "brand", size = "md", icon, loadin
|
|
|
43
43
|
className: "qx-button-label",
|
|
44
44
|
"data-slot": "button-label",
|
|
45
45
|
children
|
|
46
|
-
}),
|
|
46
|
+
}), (icon || loading) && /* @__PURE__ */ jsx("span", {
|
|
47
|
+
className: "qx-button-zone",
|
|
48
|
+
"data-slot": "button-zone",
|
|
49
|
+
children: content(icon, size, loading)
|
|
50
|
+
})]
|
|
47
51
|
});
|
|
48
52
|
}
|
|
49
53
|
/**
|
package/dist/css/avatar.css
CHANGED
package/dist/css/badge.css
CHANGED
package/dist/css/button.css
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
border: 0;
|
|
19
19
|
justify-content: space-between;
|
|
20
20
|
align-items: center;
|
|
21
|
-
gap:
|
|
22
|
-
padding-inline: 14px
|
|
21
|
+
gap: 12px;
|
|
22
|
+
padding-inline: 14px 0;
|
|
23
23
|
text-decoration: none;
|
|
24
24
|
display: inline-flex;
|
|
25
25
|
position: relative;
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
block-size: var(--qx-size-control-sm);
|
|
34
34
|
font-size: var(--qx-typography-label-sm-font-size);
|
|
35
35
|
line-height: var(--qx-typography-label-sm-line-height);
|
|
36
|
-
gap:
|
|
37
|
-
padding-inline: 10px
|
|
36
|
+
gap: 8px;
|
|
37
|
+
padding-inline: 10px 0;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
.qx-button[data-size="sm"]:not([data-icon]):not([data-loading]) {
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
|
|
44
44
|
.qx-button[data-size="lg"] {
|
|
45
45
|
block-size: var(--qx-size-control-lg);
|
|
46
|
-
gap:
|
|
47
|
-
padding-inline: 16px
|
|
46
|
+
gap: 14px;
|
|
47
|
+
padding-inline: 16px 0;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
.qx-button[data-size="lg"]:not([data-icon]):not([data-loading]) {
|
|
@@ -115,6 +115,24 @@
|
|
|
115
115
|
background: var(--qx-color-bg-danger-subtle);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
.qx-button[data-tone="neutral"][data-variant="ghost"] {
|
|
119
|
+
color: var(--qx-color-text-subtle);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.qx-button[data-tone="neutral"][data-variant="ghost"]:hover:not([data-disabled]) {
|
|
123
|
+
background: var(--qx-color-bg-neutral-subtle);
|
|
124
|
+
color: var(--qx-color-text-default);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.qx-button[data-tone="neutral"][data-variant="ghost"]:active:not([data-disabled]) {
|
|
128
|
+
background: var(--qx-color-bg-neutral-subtle-pressed);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.qx-button[data-tone="neutral"]:not([data-variant="ghost"]) {
|
|
132
|
+
background: var(--qx-color-bg-neutral-bold);
|
|
133
|
+
color: var(--qx-color-text-inverse);
|
|
134
|
+
}
|
|
135
|
+
|
|
118
136
|
.qx-button[data-disabled]:not([data-loading]) {
|
|
119
137
|
background: var(--qx-color-bg-disabled);
|
|
120
138
|
color: var(--qx-color-text-disabled);
|
|
@@ -146,6 +164,43 @@
|
|
|
146
164
|
flex: none;
|
|
147
165
|
}
|
|
148
166
|
|
|
167
|
+
.qx-button-zone {
|
|
168
|
+
flex: none;
|
|
169
|
+
align-self: stretch;
|
|
170
|
+
place-items: center;
|
|
171
|
+
padding-inline: 10px;
|
|
172
|
+
display: grid;
|
|
173
|
+
position: relative;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.qx-button-zone:before {
|
|
177
|
+
content: "";
|
|
178
|
+
inline-size: var(--qx-border-width-default);
|
|
179
|
+
block-size: var(--qx-size-icon-sm);
|
|
180
|
+
opacity: .55;
|
|
181
|
+
background: currentColor;
|
|
182
|
+
position: absolute;
|
|
183
|
+
inset-block-start: 50%;
|
|
184
|
+
inset-inline-start: 0;
|
|
185
|
+
translate: 0 -50%;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.qx-button[data-size="sm"] > .qx-button-zone {
|
|
189
|
+
padding-inline: 8px;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.qx-button[data-size="sm"] > .qx-button-zone:before {
|
|
193
|
+
block-size: var(--qx-size-icon-xs);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.qx-button[data-size="lg"] > .qx-button-zone {
|
|
197
|
+
padding-inline: 12px;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.qx-button[data-size="lg"] > .qx-button-zone:before {
|
|
201
|
+
block-size: var(--qx-size-icon-md);
|
|
202
|
+
}
|
|
203
|
+
|
|
149
204
|
.qx-icon-button {
|
|
150
205
|
inline-size: var(--qx-size-control-md);
|
|
151
206
|
justify-content: center;
|
|
@@ -165,4 +220,24 @@
|
|
|
165
220
|
.qx-icon-button:not([data-icon]):not([data-loading]) {
|
|
166
221
|
padding-inline: 0;
|
|
167
222
|
}
|
|
223
|
+
|
|
224
|
+
@media (forced-colors: active) {
|
|
225
|
+
.qx-button {
|
|
226
|
+
border: var(--qx-border-width-default) solid ButtonText;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.qx-button[data-disabled]:not([data-loading]) {
|
|
230
|
+
color: graytext;
|
|
231
|
+
border-color: graytext;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.qx-button-zone:before {
|
|
235
|
+
opacity: 1;
|
|
236
|
+
background: buttontext;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.qx-button[data-disabled]:not([data-loading]) .qx-button-zone:before {
|
|
240
|
+
background: graytext;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
168
243
|
}
|
package/dist/css/checkbox.css
CHANGED
|
@@ -55,4 +55,13 @@
|
|
|
55
55
|
.qx-checkbox-mark {
|
|
56
56
|
display: flex;
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
@media (forced-colors: active) {
|
|
60
|
+
.qx-checkbox:is([data-checked], [data-indeterminate]):not([data-disabled]) {
|
|
61
|
+
forced-color-adjust: none;
|
|
62
|
+
color: highlighttext;
|
|
63
|
+
background: highlight;
|
|
64
|
+
border-color: highlight;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
58
67
|
}
|
package/dist/css/dialog.css
CHANGED
|
@@ -118,4 +118,11 @@
|
|
|
118
118
|
inset-block-start: 12px;
|
|
119
119
|
inset-inline-end: 12px;
|
|
120
120
|
}
|
|
121
|
+
|
|
122
|
+
@media (forced-colors: active) {
|
|
123
|
+
.qx-dialog {
|
|
124
|
+
border: var(--qx-border-width-default) solid CanvasText;
|
|
125
|
+
border-block-start-width: var(--qx-border-width-accent);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
121
128
|
}
|
package/dist/css/drawer.css
CHANGED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
@import "../base.css";
|
|
2
|
+
@import "../button.css";
|
|
3
|
+
@import "../visually-hidden.css";
|
|
4
|
+
|
|
5
|
+
@layer qx.components {
|
|
6
|
+
.qx-alert {
|
|
7
|
+
align-items: flex-start;
|
|
8
|
+
gap: var(--qx-space-gap-md);
|
|
9
|
+
padding: var(--qx-space-inset-md) var(--qx-space-inset-sm) var(--qx-space-inset-md)
|
|
10
|
+
var(--qx-space-inset-md);
|
|
11
|
+
border-inline-start: var(--qx-border-width-accent) solid var(--qx-color-icon-info);
|
|
12
|
+
background: var(--qx-color-bg-info-subtle);
|
|
13
|
+
color: var(--qx-color-text-default);
|
|
14
|
+
font: var(--qx-typography-body-md);
|
|
15
|
+
font-variation-settings: "GEOM" var(--qx-font-geometry-body);
|
|
16
|
+
display: flex;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.qx-alert[data-tone="success"] {
|
|
20
|
+
border-inline-start-color: var(--qx-color-icon-success);
|
|
21
|
+
background: var(--qx-color-bg-success-subtle);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.qx-alert[data-tone="warning"] {
|
|
25
|
+
border-inline-start-color: var(--qx-color-icon-warning);
|
|
26
|
+
background: var(--qx-color-bg-warning-subtle);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.qx-alert[data-tone="danger"] {
|
|
30
|
+
border-inline-start-color: var(--qx-color-icon-danger);
|
|
31
|
+
background: var(--qx-color-bg-danger-subtle);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.qx-alert-icon {
|
|
35
|
+
color: var(--qx-color-icon-info);
|
|
36
|
+
flex: none;
|
|
37
|
+
margin-block-start: 2px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
[data-tone="success"] > .qx-alert-icon {
|
|
41
|
+
color: var(--qx-color-icon-success);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
[data-tone="warning"] > .qx-alert-icon {
|
|
45
|
+
color: var(--qx-color-icon-warning);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
[data-tone="danger"] > .qx-alert-icon {
|
|
49
|
+
color: var(--qx-color-icon-danger);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.qx-alert-body {
|
|
53
|
+
min-inline-size: 0;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
flex: 1;
|
|
56
|
+
gap: 2px;
|
|
57
|
+
padding-inline-end: var(--qx-space-gap-xs);
|
|
58
|
+
display: flex;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.qx-alert-title {
|
|
62
|
+
font: var(--qx-typography-label-md);
|
|
63
|
+
font-weight: var(--qx-typography-title-sm-font-weight);
|
|
64
|
+
font-variation-settings: "GEOM" var(--qx-font-geometry-body);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.qx-alert-description {
|
|
68
|
+
color: var(--qx-color-text-subtle);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.qx-alert-actions {
|
|
72
|
+
gap: var(--qx-space-gap-sm);
|
|
73
|
+
flex-wrap: wrap;
|
|
74
|
+
margin-block-start: var(--qx-space-gap-sm);
|
|
75
|
+
display: flex;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.qx-alert-dismiss {
|
|
79
|
+
flex: none;
|
|
80
|
+
margin-block: -2px;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@media (forced-colors: active) {
|
|
84
|
+
.qx-alert {
|
|
85
|
+
border: var(--qx-border-width-default) solid CanvasText;
|
|
86
|
+
border-inline-start: var(--qx-border-width-accent) solid CanvasText;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|