@optimum-intelligence/opti-ui 0.0.0-stage → 0.3.0
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/LICENSE +23 -0
- package/README.md +244 -2
- package/dist/components/accordion/Accordion.d.ts +17 -0
- package/dist/components/accordion/Accordion.js +204 -0
- package/dist/components/accordion/Accordion.js.map +1 -0
- package/dist/components/alert/Alert.d.ts +18 -0
- package/dist/components/alert/Alert.js +164 -0
- package/dist/components/alert/Alert.js.map +1 -0
- package/dist/components/app-shell/AppShell.d.ts +97 -0
- package/dist/components/app-shell/AppShell.js +689 -0
- package/dist/components/app-shell/AppShell.js.map +1 -0
- package/dist/components/avatar/Avatar.d.ts +21 -0
- package/dist/components/avatar/Avatar.js +190 -0
- package/dist/components/avatar/Avatar.js.map +1 -0
- package/dist/components/badge/Badge.d.ts +16 -0
- package/dist/components/badge/Badge.js +94 -0
- package/dist/components/badge/Badge.js.map +1 -0
- package/dist/components/breadcrumbs/Breadcrumbs.d.ts +18 -0
- package/dist/components/breadcrumbs/Breadcrumbs.js +154 -0
- package/dist/components/breadcrumbs/Breadcrumbs.js.map +1 -0
- package/dist/components/button/Button.d.ts +23 -0
- package/dist/components/button/Button.js +159 -0
- package/dist/components/button/Button.js.map +1 -0
- package/dist/components/calendar/Calendar.d.ts +59 -0
- package/dist/components/calendar/Calendar.js +709 -0
- package/dist/components/calendar/Calendar.js.map +1 -0
- package/dist/components/calendar/date-utils.d.ts +32 -0
- package/dist/components/calendar/date-utils.js +112 -0
- package/dist/components/calendar/date-utils.js.map +1 -0
- package/dist/components/card/Card.d.ts +42 -0
- package/dist/components/card/Card.js +82 -0
- package/dist/components/card/Card.js.map +1 -0
- package/dist/components/choice/Choice.d.ts +32 -0
- package/dist/components/choice/Choice.js +371 -0
- package/dist/components/choice/Choice.js.map +1 -0
- package/dist/components/collapsible/Collapsible.d.ts +15 -0
- package/dist/components/collapsible/Collapsible.js +155 -0
- package/dist/components/collapsible/Collapsible.js.map +1 -0
- package/dist/components/combobox/Combobox.d.ts +68 -0
- package/dist/components/combobox/Combobox.js +752 -0
- package/dist/components/combobox/Combobox.js.map +1 -0
- package/dist/components/command-palette/CommandPalette.d.ts +52 -0
- package/dist/components/command-palette/CommandPalette.js +328 -0
- package/dist/components/command-palette/CommandPalette.js.map +1 -0
- package/dist/components/data-table/DataTable.d.ts +73 -0
- package/dist/components/data-table/DataTable.js +478 -0
- package/dist/components/data-table/DataTable.js.map +1 -0
- package/dist/components/data-table/DataTableContent.d.ts +35 -0
- package/dist/components/data-table/DataTableContent.js +550 -0
- package/dist/components/data-table/DataTableContent.js.map +1 -0
- package/dist/components/data-table/DataTableFilters.d.ts +15 -0
- package/dist/components/data-table/DataTableFilters.js +284 -0
- package/dist/components/data-table/DataTableFilters.js.map +1 -0
- package/dist/components/data-table/DataTableRow.d.ts +33 -0
- package/dist/components/data-table/DataTableRow.js +552 -0
- package/dist/components/data-table/DataTableRow.js.map +1 -0
- package/dist/components/data-table/context.d.ts +5 -0
- package/dist/components/data-table/context.js +14 -0
- package/dist/components/data-table/context.js.map +1 -0
- package/dist/components/data-table/layout.d.ts +60 -0
- package/dist/components/data-table/layout.js +272 -0
- package/dist/components/data-table/layout.js.map +1 -0
- package/dist/components/data-table/types.d.ts +319 -0
- package/dist/components/data-table/useDataTable.d.ts +9 -0
- package/dist/components/data-table/useDataTable.js +666 -0
- package/dist/components/data-table/useDataTable.js.map +1 -0
- package/dist/components/date-picker/DatePicker.d.ts +50 -0
- package/dist/components/date-picker/DatePicker.js +485 -0
- package/dist/components/date-picker/DatePicker.js.map +1 -0
- package/dist/components/date-picker/DateRangePicker.d.ts +39 -0
- package/dist/components/date-picker/DateRangePicker.js +339 -0
- package/dist/components/date-picker/DateRangePicker.js.map +1 -0
- package/dist/components/date-picker/PickerField.d.ts +38 -0
- package/dist/components/date-picker/PickerField.js +238 -0
- package/dist/components/date-picker/PickerField.js.map +1 -0
- package/dist/components/dialog/Dialog.d.ts +70 -0
- package/dist/components/dialog/Dialog.js +354 -0
- package/dist/components/dialog/Dialog.js.map +1 -0
- package/dist/components/drawer/Drawer.d.ts +39 -0
- package/dist/components/drawer/Drawer.js +225 -0
- package/dist/components/drawer/Drawer.js.map +1 -0
- package/dist/components/empty-state/EmptyState.d.ts +12 -0
- package/dist/components/empty-state/EmptyState.js +116 -0
- package/dist/components/empty-state/EmptyState.js.map +1 -0
- package/dist/components/field/Field.d.ts +36 -0
- package/dist/components/field/Field.js +337 -0
- package/dist/components/field/Field.js.map +1 -0
- package/dist/components/file-upload/FileUpload.d.ts +91 -0
- package/dist/components/file-upload/FileUpload.js +714 -0
- package/dist/components/file-upload/FileUpload.js.map +1 -0
- package/dist/components/input/Input.d.ts +49 -0
- package/dist/components/input/Input.js +538 -0
- package/dist/components/input/Input.js.map +1 -0
- package/dist/components/link/Link.d.ts +17 -0
- package/dist/components/link/Link.js +91 -0
- package/dist/components/link/Link.js.map +1 -0
- package/dist/components/menu/Menu.d.ts +79 -0
- package/dist/components/menu/Menu.js +615 -0
- package/dist/components/menu/Menu.js.map +1 -0
- package/dist/components/number-field/NumberField.d.ts +16 -0
- package/dist/components/number-field/NumberField.js +188 -0
- package/dist/components/number-field/NumberField.js.map +1 -0
- package/dist/components/pagination/Pagination.d.ts +34 -0
- package/dist/components/pagination/Pagination.js +244 -0
- package/dist/components/pagination/Pagination.js.map +1 -0
- package/dist/components/popover/Popover.d.ts +22 -0
- package/dist/components/popover/Popover.js +186 -0
- package/dist/components/popover/Popover.js.map +1 -0
- package/dist/components/preview-card/PreviewCard.d.ts +20 -0
- package/dist/components/preview-card/PreviewCard.js +114 -0
- package/dist/components/preview-card/PreviewCard.js.map +1 -0
- package/dist/components/progress/Progress.d.ts +20 -0
- package/dist/components/progress/Progress.js +169 -0
- package/dist/components/progress/Progress.js.map +1 -0
- package/dist/components/scroll-area/ScrollArea.d.ts +8 -0
- package/dist/components/scroll-area/ScrollArea.js +112 -0
- package/dist/components/scroll-area/ScrollArea.js.map +1 -0
- package/dist/components/search-input/SearchInput.d.ts +14 -0
- package/dist/components/search-input/SearchInput.js +114 -0
- package/dist/components/search-input/SearchInput.js.map +1 -0
- package/dist/components/select/Select.d.ts +66 -0
- package/dist/components/select/Select.js +601 -0
- package/dist/components/select/Select.js.map +1 -0
- package/dist/components/separator/Separator.d.ts +4 -0
- package/dist/components/separator/Separator.js +46 -0
- package/dist/components/separator/Separator.js.map +1 -0
- package/dist/components/skeleton/Skeleton.d.ts +16 -0
- package/dist/components/skeleton/Skeleton.js +135 -0
- package/dist/components/skeleton/Skeleton.js.map +1 -0
- package/dist/components/slider/Slider.d.ts +11 -0
- package/dist/components/slider/Slider.js +107 -0
- package/dist/components/slider/Slider.js.map +1 -0
- package/dist/components/spinner/Spinner.d.ts +9 -0
- package/dist/components/spinner/Spinner.js +78 -0
- package/dist/components/spinner/Spinner.js.map +1 -0
- package/dist/components/stack/Stack.d.ts +23 -0
- package/dist/components/stack/Stack.js +79 -0
- package/dist/components/stack/Stack.js.map +1 -0
- package/dist/components/stat-card/StatCard.d.ts +22 -0
- package/dist/components/stat-card/StatCard.js +153 -0
- package/dist/components/stat-card/StatCard.js.map +1 -0
- package/dist/components/stepper/Stepper.d.ts +30 -0
- package/dist/components/stepper/Stepper.js +131 -0
- package/dist/components/stepper/Stepper.js.map +1 -0
- package/dist/components/table/Table.d.ts +53 -0
- package/dist/components/table/Table.js +221 -0
- package/dist/components/table/Table.js.map +1 -0
- package/dist/components/tabs/Tabs.d.ts +19 -0
- package/dist/components/tabs/Tabs.js +183 -0
- package/dist/components/tabs/Tabs.js.map +1 -0
- package/dist/components/tag/Tag.d.ts +22 -0
- package/dist/components/tag/Tag.js +121 -0
- package/dist/components/tag/Tag.js.map +1 -0
- package/dist/components/toast/Toast.d.ts +34 -0
- package/dist/components/toast/Toast.js +187 -0
- package/dist/components/toast/Toast.js.map +1 -0
- package/dist/components/toggle/Toggle.d.ts +31 -0
- package/dist/components/toggle/Toggle.js +197 -0
- package/dist/components/toggle/Toggle.js.map +1 -0
- package/dist/components/toolbar/Toolbar.d.ts +21 -0
- package/dist/components/toolbar/Toolbar.js +239 -0
- package/dist/components/toolbar/Toolbar.js.map +1 -0
- package/dist/components/tooltip/Tooltip.d.ts +33 -0
- package/dist/components/tooltip/Tooltip.js +182 -0
- package/dist/components/tooltip/Tooltip.js.map +1 -0
- package/dist/components/typography/Typography.d.ts +32 -0
- package/dist/components/typography/Typography.js +183 -0
- package/dist/components/typography/Typography.js.map +1 -0
- package/dist/fonts.css +3 -0
- package/dist/icons/index.d.ts +133 -0
- package/dist/icons/index.js +182 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.js +58 -0
- package/dist/opti-ui.css +5692 -0
- package/dist/theme/ThemeProvider.d.ts +22 -0
- package/dist/theme/ThemeProvider.js +115 -0
- package/dist/theme/ThemeProvider.js.map +1 -0
- package/dist/theme/index.d.ts +2 -0
- package/dist/utils/cx.d.ts +10 -0
- package/dist/utils/cx.js +18 -0
- package/dist/utils/cx.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/portal.d.ts +8 -0
- package/dist/utils/portal.js +16 -0
- package/dist/utils/portal.js.map +1 -0
- package/dist/utils/primitive.d.ts +13 -0
- package/dist/utils/primitive.js +61 -0
- package/dist/utils/primitive.js.map +1 -0
- package/dist/utils/search.d.ts +4 -0
- package/dist/utils/search.js +15 -0
- package/dist/utils/search.js.map +1 -0
- package/package.json +71 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright (c) 2026 Optimum Intelligence. All rights reserved.
|
|
2
|
+
|
|
3
|
+
PROPRIETARY LICENSE
|
|
4
|
+
|
|
5
|
+
This software and associated files (the "Software") are the confidential and
|
|
6
|
+
proprietary property of Optimum Intelligence ("Optimum"). The Software is
|
|
7
|
+
published to a public registry for distribution convenience only; publication
|
|
8
|
+
does not grant any license to the public.
|
|
9
|
+
|
|
10
|
+
Permission to install, use, and modify the Software is granted solely to
|
|
11
|
+
Optimum and to its employees and contractors acting on Optimum's behalf, for
|
|
12
|
+
Optimum's internal business purposes and for products and services operated by
|
|
13
|
+
Optimum.
|
|
14
|
+
|
|
15
|
+
Without Optimum's prior written permission, you may not: (a) use the Software
|
|
16
|
+
for any other purpose; (b) copy, redistribute, sublicense, sell, or publish the
|
|
17
|
+
Software or any derivative of it; or (c) remove or alter this notice.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
22
|
+
OPTIMUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM THE
|
|
23
|
+
USE OF THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,245 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Opti UI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Optimum Intelligence's shared React component library. It is built on [Base UI](https://base-ui.com) for
|
|
4
|
+
behaviour and accessibility, with a Poppins/Montserrat look: deep purple `#271645`, accent `#63537d`,
|
|
5
|
+
soft tinted borders and rounded controls. Everything is themeable through CSS variables.
|
|
6
|
+
|
|
7
|
+
## Showcase
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm ci
|
|
11
|
+
npm run dev # http://127.0.0.1:5173
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The showcase covers every component with live examples, code snippets and prop tables, plus a dashboard
|
|
15
|
+
example. **Customize** in the top bar re-themes the whole app live (mode, brand/accent colors,
|
|
16
|
+
radius, button shape, typeface) and gives you the CSS to paste into your own app.
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm test # typecheck, library build, smoke tests on dist/
|
|
20
|
+
npm run build # library → dist/ (ESM per module, opti-ui.css, .d.ts)
|
|
21
|
+
npm run build:showcase # static showcase → showcase-dist/
|
|
22
|
+
npm pack # tarball for installing in other projects
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Using the package
|
|
26
|
+
|
|
27
|
+
React 19 is a peer dependency; the build is precompiled with React Compiler. `@base-ui/react` is installed with the package.
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import '@optimum-intelligence/opti-ui/styles.css';
|
|
31
|
+
import '@optimum-intelligence/opti-ui/fonts.css'; // optional: loads Poppins + Montserrat from Google Fonts
|
|
32
|
+
import { Button, Card, CardTitle, ToastProvider, Tooltip } from '@optimum-intelligence/opti-ui';
|
|
33
|
+
|
|
34
|
+
export function App() {
|
|
35
|
+
return (
|
|
36
|
+
<Tooltip.Provider>
|
|
37
|
+
<ToastProvider>
|
|
38
|
+
<Card>
|
|
39
|
+
<CardTitle>Monthly energy</CardTitle>
|
|
40
|
+
<Button>Export report</Button>
|
|
41
|
+
</Card>
|
|
42
|
+
</ToastProvider>
|
|
43
|
+
</Tooltip.Provider>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Add `class="oui-root"` to `<body>` for the library font, text color and background. Add `oui-isolate`
|
|
49
|
+
to your app root so portalled popups stack above app content. Every module has a `'use client'` banner,
|
|
50
|
+
so the components work in Next.js App Router.
|
|
51
|
+
|
|
52
|
+
### Components
|
|
53
|
+
|
|
54
|
+
| Area | Components |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| Layout | `AppShell`, `Navbar` (+ `NavbarHeader/Brand/Section/SectionLabel/Item/Footer`), `PageHeader`, `Grid`, `Stack`, `Card` (+ parts), `StatCard`, `Separator`, `ScrollArea` |
|
|
57
|
+
| Actions | `Button`, `IconButton`, `Toggle`, `ToggleGroup`, `SegmentedControl`, `Menu.*`, `ContextMenu.*`, `Toolbar.*` |
|
|
58
|
+
| Forms | `Field.*`, `Fieldset.*`, `Form`, `Input`, `TextField`, `PasswordInput`, `PasswordField`, `Textarea`, `TextareaField`, `Select` (+ parts), `Combobox` (+ parts), `Checkbox`, `CheckboxGroup`, `Radio`, `RadioGroup`, `Switch`, `NumberField`, `Slider`, `SearchInput`, `DatePicker`, `DateTimePicker`, `DateRangePicker`, `Calendar`, `RangeCalendar`, `FileUpload`, `Dropzone`, `FileItem` |
|
|
59
|
+
| Overlays | `Dialog.*` (modal, or a sheet with `placement`), `AlertDialog.*`, `Drawer` (detail side panel), `Popover.*`, `PreviewCard.*`, `Tooltip`, `ToastProvider` + `useToast()`, `CommandPalette` |
|
|
60
|
+
| Disclosure & navigation | `Tabs.*`, `Accordion.*`, `Collapsible.*`, `Breadcrumbs` + `Breadcrumb`, `Pagination`, `Stepper` |
|
|
61
|
+
| Feedback & data | `Alert`, `Badge`, `Tag`, `Avatar`, `AvatarGroup`, `Progress`, `Meter`, `Skeleton`, `SkeletonText`, `Spinner`, `Table` (+ parts), `DataTable`, `EmptyState`, `Heading`, `Text`, `Eyebrow`, `Link` |
|
|
62
|
+
| Theme | `ThemeProvider`, `createTheme`, `themeToStyle`, icons (`CheckIcon`, `ChevronDownIcon`, …) |
|
|
63
|
+
|
|
64
|
+
Components with a common one-line form can be called directly, and their parts are attached for full
|
|
65
|
+
control: `<Select items={…} />` or `<Select.Root>…<Select.Trigger/>…</Select.Root>`; the same applies to
|
|
66
|
+
`Combobox` and `Tooltip`. Compound components (`Dialog`, `Menu`, `Tabs`, …) mirror Base UI's part names,
|
|
67
|
+
so the [Base UI docs](https://base-ui.com/react/overview/quick-start) apply to them directly.
|
|
68
|
+
|
|
69
|
+
`DatePicker` and `DateTimePicker` use ISO strings as values (`"2026-03-09"`, `"2026-03-09T14:30"`), the
|
|
70
|
+
same format as native date inputs; `DateRangePicker` uses `{ start, end }` with both days inclusive.
|
|
71
|
+
Dates are displayed the same way in every locale, on a 24-hour clock: `2026-03-09 14:30:00` in fields
|
|
72
|
+
(`formatDate`) and `2026. March 9. 14:30` where they are written out (`formatDateLong`); the locale only
|
|
73
|
+
translates month and weekday names.
|
|
74
|
+
|
|
75
|
+
`DataTable` handles search, filters, sorting, pagination, selection, row actions and inline editing for
|
|
76
|
+
rows held in memory. Columns declare what they take part in:
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
const columns: DataTableColumn<Driver>[] = [
|
|
80
|
+
{ id: 'badge', header: 'Badge', mono: true, searchMode: 'exact' },
|
|
81
|
+
{ id: 'name', header: 'Name', edit: 'text' },
|
|
82
|
+
{ id: 'depot', header: 'Depot', filter: 'select', edit: { type: 'select', options: depots } },
|
|
83
|
+
{ id: 'active', header: 'Active', filter: 'toggle', edit: 'checkbox', cell: (row) => <StatusBadge on={row.active} /> },
|
|
84
|
+
{ id: 'hired', header: 'Hired', filter: 'dateRange' },
|
|
85
|
+
{ id: 'notes', header: 'Notes', hidden: true }, // searched, not shown
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
<DataTable
|
|
89
|
+
data={drivers}
|
|
90
|
+
columns={columns}
|
|
91
|
+
locale="hu"
|
|
92
|
+
filters={[{ id: 'new', type: 'toggle', label: 'New this month', match: isNew }]}
|
|
93
|
+
rowActions={(row) => [{ label: 'Locate', icon: <MapPin />, onClick: () => locate(row) }]}
|
|
94
|
+
rowTone={(row) => (row.suspended ? 'danger' : undefined)}
|
|
95
|
+
onRowSave={(row) => api.saveDriver(row)}
|
|
96
|
+
onRowDelete={(row) => confirmDelete(row)}
|
|
97
|
+
/>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
A `select` filter collects its options from the rows unless you pass `options`; a `toggle` keeps truthy
|
|
101
|
+
values, or the rows passing its `match`; a `dateRange` includes both of its days. `onRowSave` adds the
|
|
102
|
+
edit action and receives the edited row: return a promise to keep the row open while it saves, and reject
|
|
103
|
+
it to leave the row open for another try.
|
|
104
|
+
|
|
105
|
+
Every piece of state (`search`, `filterValues`, `sort`, `page`, `pageSize`, `selection`) works
|
|
106
|
+
uncontrolled, or controlled with its `on…Change` callback. With `mode="server"` the table renders the page
|
|
107
|
+
it is given and reports those changes, so the API does the work; typing in the search box is debounced
|
|
108
|
+
by 300 ms (`searchDebounce`). Pass `total`, `loading` and `error` alongside:
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
<DataTable
|
|
112
|
+
mode="server"
|
|
113
|
+
data={data?.rows ?? []}
|
|
114
|
+
total={data?.total}
|
|
115
|
+
columns={columns}
|
|
116
|
+
loading={isFetching}
|
|
117
|
+
error={error?.message}
|
|
118
|
+
onRetry={refetch}
|
|
119
|
+
page={page}
|
|
120
|
+
onPageChange={setPage}
|
|
121
|
+
onSortChange={setSort}
|
|
122
|
+
onSearchChange={setSearch}
|
|
123
|
+
onFilterValuesChange={setFilters}
|
|
124
|
+
/>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The table measures its columns once, with the longest values of all rows, and then holds their widths:
|
|
128
|
+
paging, sorting, filtering and editing a row move nothing, and a short last page stays as tall as a full
|
|
129
|
+
one. The widths are measured again when the table is resized. A column's `width` is a starting point and
|
|
130
|
+
`minWidth` a floor; `truncate` cuts long text with an ellipsis instead of wrapping it. `layout="auto"`
|
|
131
|
+
hands the widths back to the browser.
|
|
132
|
+
|
|
133
|
+
For thousands of rows, `virtualized` renders only the ones in view inside `maxHeight` (default `32rem`)
|
|
134
|
+
and turns pagination off. Rows are then one line high and every column fits its longest value, so mark
|
|
135
|
+
long-text columns `truncate`. `onEndReached` loads more rows as the end is scrolled into view:
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
<DataTable data={shipments} columns={columns} virtualized maxHeight={480} />
|
|
139
|
+
|
|
140
|
+
<DataTable
|
|
141
|
+
mode="server"
|
|
142
|
+
data={rows}
|
|
143
|
+
total={total}
|
|
144
|
+
columns={columns}
|
|
145
|
+
loading={isFetchingNextPage}
|
|
146
|
+
paginated={false}
|
|
147
|
+
maxHeight={480}
|
|
148
|
+
onEndReached={fetchNextPage}
|
|
149
|
+
/>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Rows of another height take `virtualized={{ rowHeight: 56 }}`. A row scrolled far out of view is
|
|
153
|
+
unmounted, so focus inside it is lost; an edit in progress is kept and shows again when the row returns.
|
|
154
|
+
|
|
155
|
+
For another layout, `useDataTable` takes the same options and returns the state and the processed rows,
|
|
156
|
+
and the parts render it wherever you place them inside `DataTable.Root`:
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
const table = useDataTable({ data, columns });
|
|
160
|
+
|
|
161
|
+
<DataTable.Root table={table}>
|
|
162
|
+
<DataTable.Toolbar>
|
|
163
|
+
<DataTable.Search />
|
|
164
|
+
<DataTable.Filter id="depot" />
|
|
165
|
+
<DataTable.Actions>
|
|
166
|
+
<DataTable.Summary />
|
|
167
|
+
<Button onClick={() => exportCsv(table.rows.map(({ row }) => row))}>Export</Button>
|
|
168
|
+
</DataTable.Actions>
|
|
169
|
+
</DataTable.Toolbar>
|
|
170
|
+
<DataTable.Content density="compact" maxHeight={480} />
|
|
171
|
+
<DataTable.Pagination />
|
|
172
|
+
</DataTable.Root>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
`DataTable.Filters` renders every filter with a clear button, and `useDataTableContext()` gives your own
|
|
176
|
+
components the same table.
|
|
177
|
+
|
|
178
|
+
`FileUpload` collects `File` objects and leaves the upload to you; report its progress per file through
|
|
179
|
+
`fileState`. Components with built-in text (`DataTable`, `Pagination`, `DatePicker`, `DateRangePicker`,
|
|
180
|
+
`Calendar`, `FileUpload`, `Stepper`) take a `labels` prop for translation, and the date components take a
|
|
181
|
+
`locale`.
|
|
182
|
+
|
|
183
|
+
## Customization
|
|
184
|
+
|
|
185
|
+
Start with the simplest option that does what you need:
|
|
186
|
+
|
|
187
|
+
1. **Tokens.** Every color, radius, shadow, font, size and duration is a `--oui-*` custom property. Most
|
|
188
|
+
colors are derived from two inputs with `color-mix()`, so a product theme is often just two values:
|
|
189
|
+
|
|
190
|
+
```css
|
|
191
|
+
:root {
|
|
192
|
+
--oui-color-brand: #0f2a44; /* deep base: primary buttons, headings, navbar, muted text */
|
|
193
|
+
--oui-color-accent: #1f8fd6; /* focus rings, selection, borders, tints */
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
2. **Scoped themes.** `<ThemeProvider theme={{ 'color-accent': '#1f8fd6' }} mode="dark">` applies tokens to a
|
|
198
|
+
subtree. Popups opened inside are portalled into the provider, so they inherit the same theme. For
|
|
199
|
+
dark mode across the whole app, set `data-oui-theme="dark"` on `<html>`.
|
|
200
|
+
3. **Component variables.** Use these per instance or globally, e.g. `--oui-button-radius`,
|
|
201
|
+
`--oui-button-height`, `--oui-input-height`, `--oui-card-padding`, `--oui-card-radius`,
|
|
202
|
+
`--oui-dialog-width`, `--oui-navbar-width`, `--oui-navbar-collapsed-width`, `--oui-switch-width`, `--oui-progress-height`.
|
|
203
|
+
4. **Classes.** All library CSS is inside cascade layers (`oui.tokens < oui.base < oui.components`).
|
|
204
|
+
Any unlayered CSS in your app overrides it, whatever its specificity, so `!important` is never
|
|
205
|
+
needed. Every part has a stable class (`oui-select__trigger`, `oui-dialog__footer`, …).
|
|
206
|
+
5. **State attributes.** Style states through Base UI's data attributes (`[data-checked]`,
|
|
207
|
+
`[data-popup-open]`, `[data-highlighted]`, …) and the library's own (`[data-variant]`, `[data-size]`,
|
|
208
|
+
`[data-tone]`). `className` also accepts a function of component state.
|
|
209
|
+
6. **The render prop.** Swap the rendered element and keep the styles and behaviour:
|
|
210
|
+
`<NavbarItem render={<NavLink to="/fleet" />}>`,
|
|
211
|
+
`<Button render={<a href="…" />} nativeButton={false}>`.
|
|
212
|
+
|
|
213
|
+
**Tailwind v4:** declare the layer order so utilities still win over library styles:
|
|
214
|
+
`@layer theme, base, oui, components, utilities;`
|
|
215
|
+
|
|
216
|
+
## Project layout
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
src/
|
|
220
|
+
styles/ tokens, layer order, shared Sass mixins, stylesheet entry
|
|
221
|
+
theme/ ThemeProvider, helpers
|
|
222
|
+
components/ one folder per component: Component.tsx + component.scss
|
|
223
|
+
icons/ small built-in icon set (stroke icons, currentColor)
|
|
224
|
+
utils/ class helpers, render-prop primitive, portal container
|
|
225
|
+
showcase/ documentation app (consumes src/ directly)
|
|
226
|
+
tests/ smoke tests against dist/
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Conventions: kebab-case component folders, BEM-style `oui-block__element` classes, and variants as
|
|
230
|
+
`data-*` attributes, never modifier classes. Private custom properties are prefixed `--_`; public
|
|
231
|
+
ones `--oui-`.
|
|
232
|
+
|
|
233
|
+
## Docker / Dokploy deployment
|
|
234
|
+
|
|
235
|
+
The Docker image builds the static showcase and serves it with Nginx on port 80. It needs no
|
|
236
|
+
environment variables or persistent storage.
|
|
237
|
+
|
|
238
|
+
```sh
|
|
239
|
+
docker build -t opti-ui-showcase .
|
|
240
|
+
docker run --rm -p 8080:80 opti-ui-showcase # http://localhost:8080
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
In Dokploy, create an **Application** for this repository, select the **Dockerfile** build type
|
|
244
|
+
(path `Dockerfile`, context `.`), add a domain with container port `80`, and deploy. The image includes
|
|
245
|
+
an HTTP health check.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Accordion as BaseAccordion } from '@base-ui/react/accordion';
|
|
2
|
+
export interface AccordionRootProps extends BaseAccordion.Root.Props {
|
|
3
|
+
/** `separated` renders each item as its own card; `plain` uses dividers. */
|
|
4
|
+
variant?: 'separated' | 'plain';
|
|
5
|
+
}
|
|
6
|
+
declare function AccordionRoot({ variant, className, ref, ...props }: AccordionRootProps): import("react").JSX.Element;
|
|
7
|
+
declare function AccordionItem({ className, ref, ...props }: BaseAccordion.Item.Props): import("react").JSX.Element;
|
|
8
|
+
/** Header + trigger + chevron in one. */
|
|
9
|
+
declare function AccordionTrigger({ className, children, ref, ...props }: BaseAccordion.Trigger.Props): import("react").JSX.Element;
|
|
10
|
+
declare function AccordionPanel({ className, children, ref, ...props }: BaseAccordion.Panel.Props): import("react").JSX.Element;
|
|
11
|
+
export declare const Accordion: {
|
|
12
|
+
Root: typeof AccordionRoot;
|
|
13
|
+
Item: typeof AccordionItem;
|
|
14
|
+
Trigger: typeof AccordionTrigger;
|
|
15
|
+
Panel: typeof AccordionPanel;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { withClass } from "../../utils/cx.js";
|
|
3
|
+
import { ChevronDownIcon } from "../../icons/index.js";
|
|
4
|
+
import { c } from "react/compiler-runtime";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Accordion } from "@base-ui/react/accordion";
|
|
7
|
+
//#region src/components/accordion/Accordion.tsx
|
|
8
|
+
function AccordionRoot(t0) {
|
|
9
|
+
const $ = c(12);
|
|
10
|
+
let className;
|
|
11
|
+
let props;
|
|
12
|
+
let ref;
|
|
13
|
+
let t1;
|
|
14
|
+
if ($[0] !== t0) {
|
|
15
|
+
({variant: t1, className, ref, ...props} = t0);
|
|
16
|
+
$[0] = t0;
|
|
17
|
+
$[1] = className;
|
|
18
|
+
$[2] = props;
|
|
19
|
+
$[3] = ref;
|
|
20
|
+
$[4] = t1;
|
|
21
|
+
} else {
|
|
22
|
+
className = $[1];
|
|
23
|
+
props = $[2];
|
|
24
|
+
ref = $[3];
|
|
25
|
+
t1 = $[4];
|
|
26
|
+
}
|
|
27
|
+
const variant = t1 === void 0 ? "plain" : t1;
|
|
28
|
+
let t2;
|
|
29
|
+
if ($[5] !== className) {
|
|
30
|
+
t2 = withClass("oui-accordion", className);
|
|
31
|
+
$[5] = className;
|
|
32
|
+
$[6] = t2;
|
|
33
|
+
} else t2 = $[6];
|
|
34
|
+
let t3;
|
|
35
|
+
if ($[7] !== props || $[8] !== ref || $[9] !== t2 || $[10] !== variant) {
|
|
36
|
+
t3 = /* @__PURE__ */ jsx(Accordion.Root, {
|
|
37
|
+
ref,
|
|
38
|
+
className: t2,
|
|
39
|
+
"data-variant": variant,
|
|
40
|
+
...props
|
|
41
|
+
});
|
|
42
|
+
$[7] = props;
|
|
43
|
+
$[8] = ref;
|
|
44
|
+
$[9] = t2;
|
|
45
|
+
$[10] = variant;
|
|
46
|
+
$[11] = t3;
|
|
47
|
+
} else t3 = $[11];
|
|
48
|
+
return t3;
|
|
49
|
+
}
|
|
50
|
+
function AccordionItem(t0) {
|
|
51
|
+
const $ = c(10);
|
|
52
|
+
let className;
|
|
53
|
+
let props;
|
|
54
|
+
let ref;
|
|
55
|
+
if ($[0] !== t0) {
|
|
56
|
+
({className, ref, ...props} = t0);
|
|
57
|
+
$[0] = t0;
|
|
58
|
+
$[1] = className;
|
|
59
|
+
$[2] = props;
|
|
60
|
+
$[3] = ref;
|
|
61
|
+
} else {
|
|
62
|
+
className = $[1];
|
|
63
|
+
props = $[2];
|
|
64
|
+
ref = $[3];
|
|
65
|
+
}
|
|
66
|
+
let t1;
|
|
67
|
+
if ($[4] !== className) {
|
|
68
|
+
t1 = withClass("oui-accordion__item", className);
|
|
69
|
+
$[4] = className;
|
|
70
|
+
$[5] = t1;
|
|
71
|
+
} else t1 = $[5];
|
|
72
|
+
let t2;
|
|
73
|
+
if ($[6] !== props || $[7] !== ref || $[8] !== t1) {
|
|
74
|
+
t2 = /* @__PURE__ */ jsx(Accordion.Item, {
|
|
75
|
+
ref,
|
|
76
|
+
className: t1,
|
|
77
|
+
...props
|
|
78
|
+
});
|
|
79
|
+
$[6] = props;
|
|
80
|
+
$[7] = ref;
|
|
81
|
+
$[8] = t1;
|
|
82
|
+
$[9] = t2;
|
|
83
|
+
} else t2 = $[9];
|
|
84
|
+
return t2;
|
|
85
|
+
}
|
|
86
|
+
/** Header + trigger + chevron in one. */
|
|
87
|
+
function AccordionTrigger(t0) {
|
|
88
|
+
const $ = c(15);
|
|
89
|
+
let children;
|
|
90
|
+
let className;
|
|
91
|
+
let props;
|
|
92
|
+
let ref;
|
|
93
|
+
if ($[0] !== t0) {
|
|
94
|
+
({className, children, ref, ...props} = t0);
|
|
95
|
+
$[0] = t0;
|
|
96
|
+
$[1] = children;
|
|
97
|
+
$[2] = className;
|
|
98
|
+
$[3] = props;
|
|
99
|
+
$[4] = ref;
|
|
100
|
+
} else {
|
|
101
|
+
children = $[1];
|
|
102
|
+
className = $[2];
|
|
103
|
+
props = $[3];
|
|
104
|
+
ref = $[4];
|
|
105
|
+
}
|
|
106
|
+
let t1;
|
|
107
|
+
if ($[5] !== className) {
|
|
108
|
+
t1 = withClass("oui-accordion__trigger", className);
|
|
109
|
+
$[5] = className;
|
|
110
|
+
$[6] = t1;
|
|
111
|
+
} else t1 = $[6];
|
|
112
|
+
let t2;
|
|
113
|
+
if ($[7] !== children) {
|
|
114
|
+
t2 = /* @__PURE__ */ jsx("span", {
|
|
115
|
+
className: "oui-accordion__trigger-label",
|
|
116
|
+
children
|
|
117
|
+
});
|
|
118
|
+
$[7] = children;
|
|
119
|
+
$[8] = t2;
|
|
120
|
+
} else t2 = $[8];
|
|
121
|
+
let t3;
|
|
122
|
+
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
|
123
|
+
t3 = /* @__PURE__ */ jsx(ChevronDownIcon, { className: "oui-accordion__chevron" });
|
|
124
|
+
$[9] = t3;
|
|
125
|
+
} else t3 = $[9];
|
|
126
|
+
let t4;
|
|
127
|
+
if ($[10] !== props || $[11] !== ref || $[12] !== t1 || $[13] !== t2) {
|
|
128
|
+
t4 = /* @__PURE__ */ jsx(Accordion.Header, {
|
|
129
|
+
className: "oui-accordion__header",
|
|
130
|
+
children: /* @__PURE__ */ jsxs(Accordion.Trigger, {
|
|
131
|
+
ref,
|
|
132
|
+
className: t1,
|
|
133
|
+
...props,
|
|
134
|
+
children: [t2, t3]
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
$[10] = props;
|
|
138
|
+
$[11] = ref;
|
|
139
|
+
$[12] = t1;
|
|
140
|
+
$[13] = t2;
|
|
141
|
+
$[14] = t4;
|
|
142
|
+
} else t4 = $[14];
|
|
143
|
+
return t4;
|
|
144
|
+
}
|
|
145
|
+
function AccordionPanel(t0) {
|
|
146
|
+
const $ = c(14);
|
|
147
|
+
let children;
|
|
148
|
+
let className;
|
|
149
|
+
let props;
|
|
150
|
+
let ref;
|
|
151
|
+
if ($[0] !== t0) {
|
|
152
|
+
({className, children, ref, ...props} = t0);
|
|
153
|
+
$[0] = t0;
|
|
154
|
+
$[1] = children;
|
|
155
|
+
$[2] = className;
|
|
156
|
+
$[3] = props;
|
|
157
|
+
$[4] = ref;
|
|
158
|
+
} else {
|
|
159
|
+
children = $[1];
|
|
160
|
+
className = $[2];
|
|
161
|
+
props = $[3];
|
|
162
|
+
ref = $[4];
|
|
163
|
+
}
|
|
164
|
+
let t1;
|
|
165
|
+
if ($[5] !== className) {
|
|
166
|
+
t1 = withClass("oui-accordion__panel", className);
|
|
167
|
+
$[5] = className;
|
|
168
|
+
$[6] = t1;
|
|
169
|
+
} else t1 = $[6];
|
|
170
|
+
let t2;
|
|
171
|
+
if ($[7] !== children) {
|
|
172
|
+
t2 = /* @__PURE__ */ jsx("div", {
|
|
173
|
+
className: "oui-accordion__content",
|
|
174
|
+
children
|
|
175
|
+
});
|
|
176
|
+
$[7] = children;
|
|
177
|
+
$[8] = t2;
|
|
178
|
+
} else t2 = $[8];
|
|
179
|
+
let t3;
|
|
180
|
+
if ($[9] !== props || $[10] !== ref || $[11] !== t1 || $[12] !== t2) {
|
|
181
|
+
t3 = /* @__PURE__ */ jsx(Accordion.Panel, {
|
|
182
|
+
ref,
|
|
183
|
+
className: t1,
|
|
184
|
+
...props,
|
|
185
|
+
children: t2
|
|
186
|
+
});
|
|
187
|
+
$[9] = props;
|
|
188
|
+
$[10] = ref;
|
|
189
|
+
$[11] = t1;
|
|
190
|
+
$[12] = t2;
|
|
191
|
+
$[13] = t3;
|
|
192
|
+
} else t3 = $[13];
|
|
193
|
+
return t3;
|
|
194
|
+
}
|
|
195
|
+
var Accordion$1 = {
|
|
196
|
+
Root: AccordionRoot,
|
|
197
|
+
Item: AccordionItem,
|
|
198
|
+
Trigger: AccordionTrigger,
|
|
199
|
+
Panel: AccordionPanel
|
|
200
|
+
};
|
|
201
|
+
//#endregion
|
|
202
|
+
export { Accordion$1 as Accordion };
|
|
203
|
+
|
|
204
|
+
//# sourceMappingURL=Accordion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Accordion.js","names":["Accordion","BaseAccordion","withClass","ChevronDownIcon","AccordionRootProps","Root","Props","variant","AccordionRoot","t0","$","_c","className","props","ref","t1","undefined","t2","t3","AccordionItem","AccordionTrigger","children","Symbol","for","t4","AccordionPanel","Item","Trigger","Panel","_c","BaseAccordion","Accordion"],"sources":["../../../src/components/accordion/Accordion.tsx"],"sourcesContent":["import { Accordion as BaseAccordion } from '@base-ui/react/accordion';\nimport { withClass } from '../../utils/cx';\nimport { ChevronDownIcon } from '../../icons';\n\nexport interface AccordionRootProps extends BaseAccordion.Root.Props {\n /** `separated` renders each item as its own card; `plain` uses dividers. */\n variant?: 'separated' | 'plain';\n}\n\nfunction AccordionRoot({ variant = 'plain', className, ref, ...props }: AccordionRootProps) {\n return (\n <BaseAccordion.Root ref={ref} className={withClass('oui-accordion', className)} data-variant={variant} {...props} />\n );\n}\n\nfunction AccordionItem({ className, ref, ...props }: BaseAccordion.Item.Props) {\n return <BaseAccordion.Item ref={ref} className={withClass('oui-accordion__item', className)} {...props} />;\n}\n\n/** Header + trigger + chevron in one. */\nfunction AccordionTrigger({ className, children, ref, ...props }: BaseAccordion.Trigger.Props) {\n return (\n <BaseAccordion.Header className=\"oui-accordion__header\">\n <BaseAccordion.Trigger ref={ref} className={withClass('oui-accordion__trigger', className)} {...props}>\n <span className=\"oui-accordion__trigger-label\">{children}</span>\n <ChevronDownIcon className=\"oui-accordion__chevron\" />\n </BaseAccordion.Trigger>\n </BaseAccordion.Header>\n );\n}\n\nfunction AccordionPanel({ className, children, ref, ...props }: BaseAccordion.Panel.Props) {\n return (\n <BaseAccordion.Panel ref={ref} className={withClass('oui-accordion__panel', className)} {...props}>\n <div className=\"oui-accordion__content\">{children}</div>\n </BaseAccordion.Panel>\n );\n}\n\nexport const Accordion = {\n Root: AccordionRoot,\n Item: AccordionItem,\n Trigger: AccordionTrigger,\n Panel: AccordionPanel,\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type AlertTone = 'info' | 'success' | 'warning' | 'danger' | 'neutral';
|
|
3
|
+
export interface AlertProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
4
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
5
|
+
tone?: AlertTone;
|
|
6
|
+
/** `soft` (tinted, default) or `outline`. */
|
|
7
|
+
variant?: 'soft' | 'outline';
|
|
8
|
+
title?: React.ReactNode;
|
|
9
|
+
/** Custom icon, or `false` to hide it. */
|
|
10
|
+
icon?: React.ReactNode | false;
|
|
11
|
+
/** Buttons rendered after the message. */
|
|
12
|
+
actions?: React.ReactNode;
|
|
13
|
+
/** Shows a dismiss button. */
|
|
14
|
+
onDismiss?: () => void;
|
|
15
|
+
dismissLabel?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Inline message for page- or section-level feedback. */
|
|
18
|
+
export declare function Alert({ tone, variant, title, icon, actions, onDismiss, dismissLabel, className, children, ref, ...props }: AlertProps): React.JSX.Element;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "../../utils/cx.js";
|
|
3
|
+
import { CircleCheckIcon, CircleXIcon, InfoIcon, TriangleAlertIcon, XIcon } from "../../icons/index.js";
|
|
4
|
+
import { IconButton } from "../button/Button.js";
|
|
5
|
+
import { c } from "react/compiler-runtime";
|
|
6
|
+
import "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/components/alert/Alert.tsx
|
|
9
|
+
var defaultIcons = {
|
|
10
|
+
info: /* @__PURE__ */ jsx(InfoIcon, {}),
|
|
11
|
+
neutral: /* @__PURE__ */ jsx(InfoIcon, {}),
|
|
12
|
+
success: /* @__PURE__ */ jsx(CircleCheckIcon, {}),
|
|
13
|
+
warning: /* @__PURE__ */ jsx(TriangleAlertIcon, {}),
|
|
14
|
+
danger: /* @__PURE__ */ jsx(CircleXIcon, {})
|
|
15
|
+
};
|
|
16
|
+
/** Inline message for page- or section-level feedback. */
|
|
17
|
+
function Alert(t0) {
|
|
18
|
+
const $ = c(39);
|
|
19
|
+
let actions;
|
|
20
|
+
let children;
|
|
21
|
+
let className;
|
|
22
|
+
let icon;
|
|
23
|
+
let onDismiss;
|
|
24
|
+
let props;
|
|
25
|
+
let ref;
|
|
26
|
+
let t1;
|
|
27
|
+
let t2;
|
|
28
|
+
let t3;
|
|
29
|
+
let title;
|
|
30
|
+
if ($[0] !== t0) {
|
|
31
|
+
({tone: t1, variant: t2, title, icon, actions, onDismiss, dismissLabel: t3, className, children, ref, ...props} = t0);
|
|
32
|
+
$[0] = t0;
|
|
33
|
+
$[1] = actions;
|
|
34
|
+
$[2] = children;
|
|
35
|
+
$[3] = className;
|
|
36
|
+
$[4] = icon;
|
|
37
|
+
$[5] = onDismiss;
|
|
38
|
+
$[6] = props;
|
|
39
|
+
$[7] = ref;
|
|
40
|
+
$[8] = t1;
|
|
41
|
+
$[9] = t2;
|
|
42
|
+
$[10] = t3;
|
|
43
|
+
$[11] = title;
|
|
44
|
+
} else {
|
|
45
|
+
actions = $[1];
|
|
46
|
+
children = $[2];
|
|
47
|
+
className = $[3];
|
|
48
|
+
icon = $[4];
|
|
49
|
+
onDismiss = $[5];
|
|
50
|
+
props = $[6];
|
|
51
|
+
ref = $[7];
|
|
52
|
+
t1 = $[8];
|
|
53
|
+
t2 = $[9];
|
|
54
|
+
t3 = $[10];
|
|
55
|
+
title = $[11];
|
|
56
|
+
}
|
|
57
|
+
const tone = t1 === void 0 ? "info" : t1;
|
|
58
|
+
const variant = t2 === void 0 ? "soft" : t2;
|
|
59
|
+
const dismissLabel = t3 === void 0 ? "Dismiss" : t3;
|
|
60
|
+
const urgent = tone === "danger" || tone === "warning";
|
|
61
|
+
const iconNode = icon === false ? null : icon ?? defaultIcons[tone];
|
|
62
|
+
const t4 = urgent ? "alert" : "status";
|
|
63
|
+
let t5;
|
|
64
|
+
if ($[12] !== className) {
|
|
65
|
+
t5 = cx("oui-alert", className);
|
|
66
|
+
$[12] = className;
|
|
67
|
+
$[13] = t5;
|
|
68
|
+
} else t5 = $[13];
|
|
69
|
+
let t6;
|
|
70
|
+
if ($[14] !== iconNode) {
|
|
71
|
+
t6 = iconNode && /* @__PURE__ */ jsx("span", {
|
|
72
|
+
className: "oui-alert__icon",
|
|
73
|
+
children: iconNode
|
|
74
|
+
});
|
|
75
|
+
$[14] = iconNode;
|
|
76
|
+
$[15] = t6;
|
|
77
|
+
} else t6 = $[15];
|
|
78
|
+
let t7;
|
|
79
|
+
if ($[16] !== title) {
|
|
80
|
+
t7 = title && /* @__PURE__ */ jsx("p", {
|
|
81
|
+
className: "oui-alert__title",
|
|
82
|
+
children: title
|
|
83
|
+
});
|
|
84
|
+
$[16] = title;
|
|
85
|
+
$[17] = t7;
|
|
86
|
+
} else t7 = $[17];
|
|
87
|
+
let t8;
|
|
88
|
+
if ($[18] !== children) {
|
|
89
|
+
t8 = children && /* @__PURE__ */ jsx("div", {
|
|
90
|
+
className: "oui-alert__message",
|
|
91
|
+
children
|
|
92
|
+
});
|
|
93
|
+
$[18] = children;
|
|
94
|
+
$[19] = t8;
|
|
95
|
+
} else t8 = $[19];
|
|
96
|
+
let t9;
|
|
97
|
+
if ($[20] !== actions) {
|
|
98
|
+
t9 = actions && /* @__PURE__ */ jsx("div", {
|
|
99
|
+
className: "oui-alert__actions",
|
|
100
|
+
children: actions
|
|
101
|
+
});
|
|
102
|
+
$[20] = actions;
|
|
103
|
+
$[21] = t9;
|
|
104
|
+
} else t9 = $[21];
|
|
105
|
+
let t10;
|
|
106
|
+
if ($[22] !== t7 || $[23] !== t8 || $[24] !== t9) {
|
|
107
|
+
t10 = /* @__PURE__ */ jsxs("div", {
|
|
108
|
+
className: "oui-alert__body",
|
|
109
|
+
children: [
|
|
110
|
+
t7,
|
|
111
|
+
t8,
|
|
112
|
+
t9
|
|
113
|
+
]
|
|
114
|
+
});
|
|
115
|
+
$[22] = t7;
|
|
116
|
+
$[23] = t8;
|
|
117
|
+
$[24] = t9;
|
|
118
|
+
$[25] = t10;
|
|
119
|
+
} else t10 = $[25];
|
|
120
|
+
let t11;
|
|
121
|
+
if ($[26] !== dismissLabel || $[27] !== onDismiss) {
|
|
122
|
+
t11 = onDismiss && /* @__PURE__ */ jsx(IconButton, {
|
|
123
|
+
className: "oui-alert__dismiss",
|
|
124
|
+
size: "sm",
|
|
125
|
+
"aria-label": dismissLabel,
|
|
126
|
+
onClick: onDismiss,
|
|
127
|
+
children: /* @__PURE__ */ jsx(XIcon, {})
|
|
128
|
+
});
|
|
129
|
+
$[26] = dismissLabel;
|
|
130
|
+
$[27] = onDismiss;
|
|
131
|
+
$[28] = t11;
|
|
132
|
+
} else t11 = $[28];
|
|
133
|
+
let t12;
|
|
134
|
+
if ($[29] !== props || $[30] !== ref || $[31] !== t10 || $[32] !== t11 || $[33] !== t4 || $[34] !== t5 || $[35] !== t6 || $[36] !== tone || $[37] !== variant) {
|
|
135
|
+
t12 = /* @__PURE__ */ jsxs("div", {
|
|
136
|
+
ref,
|
|
137
|
+
role: t4,
|
|
138
|
+
className: t5,
|
|
139
|
+
"data-tone": tone,
|
|
140
|
+
"data-variant": variant,
|
|
141
|
+
...props,
|
|
142
|
+
children: [
|
|
143
|
+
t6,
|
|
144
|
+
t10,
|
|
145
|
+
t11
|
|
146
|
+
]
|
|
147
|
+
});
|
|
148
|
+
$[29] = props;
|
|
149
|
+
$[30] = ref;
|
|
150
|
+
$[31] = t10;
|
|
151
|
+
$[32] = t11;
|
|
152
|
+
$[33] = t4;
|
|
153
|
+
$[34] = t5;
|
|
154
|
+
$[35] = t6;
|
|
155
|
+
$[36] = tone;
|
|
156
|
+
$[37] = variant;
|
|
157
|
+
$[38] = t12;
|
|
158
|
+
} else t12 = $[38];
|
|
159
|
+
return t12;
|
|
160
|
+
}
|
|
161
|
+
//#endregion
|
|
162
|
+
export { Alert };
|
|
163
|
+
|
|
164
|
+
//# sourceMappingURL=Alert.js.map
|