opui-css 3.3.5 → 4.0.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/CHANGELOG.md +235 -0
- package/LICENSE +21 -21
- package/MIGRATING.md +105 -0
- package/README.md +66 -29
- package/astro/index.ts +46 -0
- package/components/AGENTS.md +247 -0
- package/components/Accordion/Accordion.astro +42 -0
- package/components/Anchor/Anchor.astro +51 -0
- package/components/Avatar/Avatar.astro +44 -0
- package/components/Badge/Badge.astro +54 -0
- package/components/Button/Button.astro +45 -0
- package/components/ButtonGroup/ButtonGroup.astro +29 -0
- package/components/Callout/Callout.astro +75 -0
- package/components/Card/Card.astro +38 -0
- package/components/Checkbox/Checkbox.astro +76 -0
- package/components/Checkbox/CheckboxInput.astro +32 -0
- package/components/Chip/Chip.astro +37 -0
- package/components/ClassicSelect/ClassicSelect.astro +83 -0
- package/components/DescriptionList/Description.astro +12 -0
- package/components/DescriptionList/DescriptionList.astro +22 -0
- package/components/DescriptionList/Item.astro +12 -0
- package/components/DescriptionList/Term.astro +12 -0
- package/components/DescriptionList/index.ts +12 -0
- package/components/Dialog/Dialog.astro +43 -0
- package/components/Divider/Divider.astro +14 -0
- package/components/Drawer/Drawer.astro +49 -0
- package/components/Drawer/DrawerFooter.astro +14 -0
- package/components/Drawer/DrawerHeader.astro +31 -0
- package/components/FieldDescription/FieldDescription.astro +13 -0
- package/components/FieldGroup/FieldGroup.astro +31 -0
- package/components/FieldLegend/FieldLegend.astro +15 -0
- package/components/FieldSet/FieldSet.astro +15 -0
- package/components/Form/Form.astro +15 -0
- package/components/IconButton/IconButton.astro +26 -0
- package/components/List/List.astro +36 -0
- package/components/ListItem/ListItem.astro +118 -0
- package/components/Progress/Progress.astro +40 -0
- package/components/Radio/Radio.astro +70 -0
- package/components/Radio/RadioInput.astro +24 -0
- package/components/Range/Range.astro +136 -0
- package/components/Select/Select.astro +106 -0
- package/components/Switch/Switch.astro +101 -0
- package/components/Switch/SwitchInput.astro +25 -0
- package/components/Table/Body.astro +13 -0
- package/components/Table/Cell.astro +13 -0
- package/components/Table/Column.astro +15 -0
- package/components/Table/ColumnGroup.astro +13 -0
- package/components/Table/Head.astro +13 -0
- package/components/Table/HeaderCell.astro +13 -0
- package/components/Table/Row.astro +13 -0
- package/components/Table/Table.astro +15 -0
- package/components/Table/index.ts +20 -0
- package/components/Tabs/Tabs.astro +28 -0
- package/components/Tabs/TabsItem.astro +47 -0
- package/components/Tabs/TabsPanel.astro +21 -0
- package/components/Tabs/TabsTab.astro +19 -0
- package/components/Tabs/index.ts +14 -0
- package/components/TextField/TextField.astro +128 -0
- package/components/Textarea/Textarea.astro +106 -0
- package/components/Toast/Toast.astro +42 -0
- package/components/ToggleButton/ToggleButton.astro +53 -0
- package/components/ToggleGroup/ToggleGroup.astro +49 -0
- package/components/Tooltip/Tooltip.astro +30 -0
- package/{src/core → core}/normalize.css +194 -196
- package/core/palette.css +59 -0
- package/{src/core → core}/utils.css +71 -60
- package/css/components/accordion.css +174 -0
- package/css/components/anchor.css +27 -0
- package/{src/themes/theme-two → css}/components/avatar.css +65 -68
- package/css/components/badge.css +107 -0
- package/css/components/button-group.css +179 -0
- package/css/components/button.css +215 -0
- package/css/components/callout.css +109 -0
- package/css/components/card.css +117 -0
- package/css/components/checkbox.css +205 -0
- package/{src/themes/theme-one → css}/components/chip.css +87 -135
- package/{src/themes/theme-two/components/definition-list.css → css/components/description-list.css} +77 -68
- package/{src/themes/theme-two → css}/components/dialog.css +68 -59
- package/css/components/divider.css +20 -0
- package/css/components/drawer.css +171 -0
- package/css/components/form.css +146 -0
- package/css/components/icon-button.css +139 -0
- package/{src/themes/theme-two → css}/components/link.css +21 -21
- package/{src/themes/theme-two → css}/components/list.css +345 -318
- package/{src/themes/theme-one → css}/components/progress.css +97 -83
- package/css/components/radio.css +172 -0
- package/css/components/range.css +337 -0
- package/{src/themes/theme-two → css}/components/select.css +169 -162
- package/{src/themes/theme-two → css}/components/spinner.css +37 -38
- package/{src/themes/theme-two → css}/components/switch.css +268 -225
- package/css/components/table.css +179 -0
- package/css/components/tabs.css +77 -0
- package/css/components/text-field.css +450 -0
- package/css/components/text-input.css +53 -0
- package/{src/themes/theme-two → css}/components/textarea.css +24 -25
- package/css/components/toast.css +161 -0
- package/css/components/toggle-button.css +87 -0
- package/css/components/toggle-group.css +56 -0
- package/css/components/tooltip.css +67 -0
- package/css/components/typography.css +585 -0
- package/{src/themes/theme-two → css}/components.css +41 -37
- package/{src/themes/theme-two → css}/imports.css +16 -16
- package/css/js/checkbox.js +21 -0
- package/css/js/toast.js +94 -0
- package/css/theme.css +132 -0
- package/dist/op.css +1001 -32
- package/dist/op.css.map +1 -0
- package/dist/opui.components.css +5135 -0
- package/dist/opui.components.css.map +1 -0
- package/dist/opui.css +6604 -0
- package/dist/opui.css.map +1 -0
- package/env.d.ts +14 -0
- package/open-props.css +9 -0
- package/package.json +64 -56
- package/dist/theme-one/components.css +0 -3869
- package/dist/theme-one/theme-one.css +0 -4424
- package/dist/theme-two/components.css +0 -3591
- package/dist/theme-two/theme-two.css +0 -4141
- package/src/open-props.css +0 -10
- package/src/themes/theme-one/components/accordion.css +0 -172
- package/src/themes/theme-one/components/alert.css +0 -85
- package/src/themes/theme-one/components/avatar.css +0 -68
- package/src/themes/theme-one/components/badge.css +0 -101
- package/src/themes/theme-one/components/button-group.css +0 -69
- package/src/themes/theme-one/components/button.css +0 -281
- package/src/themes/theme-one/components/card.css +0 -82
- package/src/themes/theme-one/components/checkbox-radio.css +0 -123
- package/src/themes/theme-one/components/definition-list.css +0 -68
- package/src/themes/theme-one/components/dialog.css +0 -59
- package/src/themes/theme-one/components/divider.css +0 -7
- package/src/themes/theme-one/components/field-group.css +0 -83
- package/src/themes/theme-one/components/field.css +0 -494
- package/src/themes/theme-one/components/icon-button.css +0 -40
- package/src/themes/theme-one/components/link.css +0 -21
- package/src/themes/theme-one/components/list.css +0 -318
- package/src/themes/theme-one/components/range.css +0 -121
- package/src/themes/theme-one/components/rich-text.css +0 -210
- package/src/themes/theme-one/components/select.css +0 -163
- package/src/themes/theme-one/components/snackbar.css +0 -148
- package/src/themes/theme-one/components/spinner.css +0 -38
- package/src/themes/theme-one/components/switch.css +0 -225
- package/src/themes/theme-one/components/tab-buttons.css +0 -120
- package/src/themes/theme-one/components/table.css +0 -92
- package/src/themes/theme-one/components/text-field.css +0 -57
- package/src/themes/theme-one/components/textarea.css +0 -25
- package/src/themes/theme-one/components/toggle-button-group.css +0 -135
- package/src/themes/theme-one/components/tooltip.css +0 -94
- package/src/themes/theme-one/components/typography.css +0 -209
- package/src/themes/theme-one/components.css +0 -37
- package/src/themes/theme-one/imports.css +0 -16
- package/src/themes/theme-one/theme.css +0 -163
- package/src/themes/theme-two/components/accordion.css +0 -172
- package/src/themes/theme-two/components/alert.css +0 -85
- package/src/themes/theme-two/components/badge.css +0 -101
- package/src/themes/theme-two/components/button-group.css +0 -50
- package/src/themes/theme-two/components/button.css +0 -229
- package/src/themes/theme-two/components/card.css +0 -82
- package/src/themes/theme-two/components/checkbox-radio.css +0 -123
- package/src/themes/theme-two/components/chip.css +0 -135
- package/src/themes/theme-two/components/divider.css +0 -7
- package/src/themes/theme-two/components/field-group.css +0 -83
- package/src/themes/theme-two/components/field.css +0 -281
- package/src/themes/theme-two/components/icon-button.css +0 -40
- package/src/themes/theme-two/components/progress.css +0 -83
- package/src/themes/theme-two/components/range.css +0 -121
- package/src/themes/theme-two/components/rich-text.css +0 -210
- package/src/themes/theme-two/components/snackbar.css +0 -148
- package/src/themes/theme-two/components/tab-buttons.css +0 -120
- package/src/themes/theme-two/components/table.css +0 -99
- package/src/themes/theme-two/components/text-field.css +0 -57
- package/src/themes/theme-two/components/toggle-button-group.css +0 -135
- package/src/themes/theme-two/components/tooltip.css +0 -94
- package/src/themes/theme-two/components/typography.css +0 -209
- package/src/themes/theme-two/theme.css +0 -158
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# UI Component Implementation Guide
|
|
2
|
+
|
|
3
|
+
This guide defines the standards for implementing reusable Astro UI components in this package (`packages/opui/components/<Name>/<Name>.astro`) based on the documentation specs at `src/docs/components/`. Use it as a reference for maintaining consistency and accessibility across the library.
|
|
4
|
+
|
|
5
|
+
**CRITICAL INSTRUCTION**: Always use components from this package (imported via the `@opui/astro` alias) and their corresponding CSS from `packages/opui/css/components/` whenever possible. Avoid writing custom CSS if an existing component or utility can achieve the desired result.
|
|
6
|
+
|
|
7
|
+
## 0. Implementation Checklist
|
|
8
|
+
|
|
9
|
+
When implementing or updating a component, ensure:
|
|
10
|
+
- [ ] **Title Export**: `export const title = "Component Name"` is present.
|
|
11
|
+
- [ ] **Props Type**: Used `type Props = { ... }` (avoid interfaces).
|
|
12
|
+
- [ ] **Sorting**: Props, Destructuring, and Classes are sorted alphabetically.
|
|
13
|
+
- [ ] **Rest Props**: `...rest` is captured and spread onto the root element.
|
|
14
|
+
- [ ] **Class Management**: Used `class:list` for all class manipulations.
|
|
15
|
+
- [ ] **ID Stability**: Used `Astro.locals.$id` for any internal element linking.
|
|
16
|
+
- [ ] **Accessibility**: ARIA labels, roles, and relationships are correctly handled.
|
|
17
|
+
- [ ] **Slot Strategy**: Named slots are used for structural content (icons, actions).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. Frontmatter Structure
|
|
22
|
+
|
|
23
|
+
Every component must follow this exact frontmatter layout:
|
|
24
|
+
|
|
25
|
+
```astro
|
|
26
|
+
---
|
|
27
|
+
type Props = {
|
|
28
|
+
[key: string]: any // Required for ...rest support
|
|
29
|
+
class?: string
|
|
30
|
+
disabled?: boolean
|
|
31
|
+
label?: string
|
|
32
|
+
size?: "small" | "large"
|
|
33
|
+
variant?: "outlined" | "tonal" | "filled"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const title = "My Component"
|
|
37
|
+
|
|
38
|
+
const {
|
|
39
|
+
class: className,
|
|
40
|
+
disabled,
|
|
41
|
+
label,
|
|
42
|
+
size,
|
|
43
|
+
variant = "outlined", // Default values in destructuring
|
|
44
|
+
...rest
|
|
45
|
+
} = Astro.props
|
|
46
|
+
---
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Key Rules:
|
|
50
|
+
- **Alphabetical Sorting**: Sort property definitions in `type Props` and variables in the destructuring statement.
|
|
51
|
+
- **REST Support**: Always include `[key: string]: any` in props and `...rest` in destructuring.
|
|
52
|
+
- **Title Export**: This is mandatory for documentation generation.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 2. Component Composition & Tags
|
|
57
|
+
|
|
58
|
+
### Dynamic Elements (Polymorphism)
|
|
59
|
+
For components that can be different HTML elements (e.g., `Button` as `<a>` or `<button>`), use a dynamic `Tag` variable.
|
|
60
|
+
|
|
61
|
+
```astro
|
|
62
|
+
---
|
|
63
|
+
const { as: Tag = Astro.props.href ? "a" : "button", ...rest } = Astro.props
|
|
64
|
+
---
|
|
65
|
+
<Tag {...rest}><slot /></Tag>
|
|
66
|
+
```
|
|
67
|
+
- **Inference**: Default to `"a"` if `href` is present.
|
|
68
|
+
- **Override**: Allow manual override via the `as` prop.
|
|
69
|
+
|
|
70
|
+
### Styling Inheritance
|
|
71
|
+
Components should often inherit styles from others (e.g., `Dialog` looking like a `Card`). Use conditional classes to apply the inherited base class.
|
|
72
|
+
|
|
73
|
+
```astro
|
|
74
|
+
<dialog class:list={["dialog", { card: variant }, variant, className]} {...rest}>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 3. Class Management
|
|
80
|
+
|
|
81
|
+
Use `class:list` exclusively. Follow this order for readability:
|
|
82
|
+
1. **Component Base Class**: The primary CSS class (e.g., `"button"`).
|
|
83
|
+
2. **State Objects**: Boolean flags (e.g., `{ active, disabled, error }`).
|
|
84
|
+
3. **Variant Props**: Direct string values from props (e.g., `size`, `variant`).
|
|
85
|
+
4. **External Class**: Always include `className` at the end to allow for overrides.
|
|
86
|
+
|
|
87
|
+
```astro
|
|
88
|
+
<div
|
|
89
|
+
class:list={[
|
|
90
|
+
"chip",
|
|
91
|
+
{
|
|
92
|
+
multiline: isMultiline,
|
|
93
|
+
selected,
|
|
94
|
+
},
|
|
95
|
+
size,
|
|
96
|
+
variant,
|
|
97
|
+
className,
|
|
98
|
+
]}
|
|
99
|
+
>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 4. Slot Patterns
|
|
105
|
+
|
|
106
|
+
### Default Slots vs Label Props
|
|
107
|
+
For simple text-based components, provide both a `label` prop and a default slot.
|
|
108
|
+
|
|
109
|
+
```astro
|
|
110
|
+
<div class="component">
|
|
111
|
+
{ (label || Astro.slots.has("default")) && (
|
|
112
|
+
<span class="text">
|
|
113
|
+
{label}
|
|
114
|
+
<slot />
|
|
115
|
+
</span>
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Named Slots (Icons & Actions)
|
|
121
|
+
Use named slots for specific functional areas. Check for existence before rendering wrapper tags.
|
|
122
|
+
|
|
123
|
+
```astro
|
|
124
|
+
<div class="card">
|
|
125
|
+
{Astro.slots.has("header") && <header><slot name="header" /></header>}
|
|
126
|
+
<slot />
|
|
127
|
+
{Astro.slots.has("actions") && <footer class="actions"><slot name="actions" /></footer>}
|
|
128
|
+
</div>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 5. Form & Input Patterns
|
|
134
|
+
|
|
135
|
+
### Label Wrapping
|
|
136
|
+
Most inputs should be wrapped in a `<label>` to provide a larger hit area and built-in accessibility.
|
|
137
|
+
|
|
138
|
+
```astro
|
|
139
|
+
<label class:list={["field", { disabled, error }]}>
|
|
140
|
+
<span class="label">{label}</span>
|
|
141
|
+
<input type="text" {...rest} />
|
|
142
|
+
{endText && <span class="end-text">{endText}</span>}
|
|
143
|
+
</label>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### End Text & ARIA
|
|
147
|
+
When providing `endText`, use `Astro.locals.$id` to link it to the input via `aria-describedby`.
|
|
148
|
+
|
|
149
|
+
```astro
|
|
150
|
+
---
|
|
151
|
+
const { $id } = Astro.locals
|
|
152
|
+
const helpId = $id("help")
|
|
153
|
+
---
|
|
154
|
+
<input aria-describedby={endText ? helpId : undefined} />
|
|
155
|
+
{endText && <span id={helpId}>{endText}</span>}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Input Attribute Mapping
|
|
159
|
+
Explicitly define and pass through native input attributes in the `Props` type for better IDE support.
|
|
160
|
+
|
|
161
|
+
```astro
|
|
162
|
+
<input
|
|
163
|
+
disabled={disabled}
|
|
164
|
+
name={name}
|
|
165
|
+
required={required}
|
|
166
|
+
type={type}
|
|
167
|
+
value={value}
|
|
168
|
+
{...rest}
|
|
169
|
+
/>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Sub-component Decomposition
|
|
173
|
+
For complex inputs (like `Checkbox` with custom visuals), split the component into a public wrapper (`Checkbox.astro`) and a private raw input (`CheckboxInput.astro`) to keep the root element clean.
|
|
174
|
+
|
|
175
|
+
### Form Structure: FieldSet, FieldLegend, FieldDescription, FieldGroup
|
|
176
|
+
When building forms, follow this nesting order inside a `FieldSet`:
|
|
177
|
+
1. `FieldLegend` - The heading/label for the fieldset
|
|
178
|
+
2. `FieldDescription` - Optional helper text
|
|
179
|
+
3. `FieldGroup` - Wrapper for the actual form controls
|
|
180
|
+
|
|
181
|
+
**Always wrap form elements in a `FieldGroup`**, never place them directly after `FieldLegend` or `FieldDescription`.
|
|
182
|
+
|
|
183
|
+
```astro
|
|
184
|
+
<!-- ✅ Correct -->
|
|
185
|
+
<FieldSet>
|
|
186
|
+
<FieldLegend>Username</FieldLegend>
|
|
187
|
+
<FieldDescription>Enter your preferred username.</FieldDescription>
|
|
188
|
+
<FieldGroup>
|
|
189
|
+
<TextField placeholder="e.g. jdoe" />
|
|
190
|
+
</FieldGroup>
|
|
191
|
+
</FieldSet>
|
|
192
|
+
|
|
193
|
+
<!-- ❌ Incorrect - TextField directly after FieldDescription -->
|
|
194
|
+
<FieldSet>
|
|
195
|
+
<FieldLegend>Username</FieldLegend>
|
|
196
|
+
<FieldDescription>Enter your preferred username.</FieldDescription>
|
|
197
|
+
<TextField placeholder="e.g. jdoe" />
|
|
198
|
+
</FieldSet>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 6. Identification & Accessibility
|
|
204
|
+
|
|
205
|
+
### Unique IDs
|
|
206
|
+
Always use `Astro.locals.$id` for IDs. This ensures stability across server and client rendering and prevents ID collisions when multiple instances of the same component are on a page.
|
|
207
|
+
|
|
208
|
+
```astro
|
|
209
|
+
const { $id } = Astro.locals
|
|
210
|
+
const fieldId = id || $id("input") // Prefer passed ID if available
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Default Icons
|
|
214
|
+
Components like `Callout` or `Toast` should provide default SVG icons within their named slots, while allowing users to override them.
|
|
215
|
+
|
|
216
|
+
```astro
|
|
217
|
+
<slot name="icon">
|
|
218
|
+
{severity === "error" && <svg>...</svg>}
|
|
219
|
+
</slot>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 7. Data-Driven Components
|
|
225
|
+
|
|
226
|
+
For repetitive structures (DescriptionLists, Menus, Selects), prefer an `items` prop alongside standard slots.
|
|
227
|
+
|
|
228
|
+
```astro
|
|
229
|
+
type Item = { label: string; value: any }
|
|
230
|
+
type Props = { items?: Item[] }
|
|
231
|
+
|
|
232
|
+
<ul>
|
|
233
|
+
{items.map(item => <li>{item.label}</li>)}
|
|
234
|
+
<slot /> <!-- Still allow manual entries -->
|
|
235
|
+
</ul>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## 8. Development Workflow
|
|
241
|
+
|
|
242
|
+
1. **Read the Spec**: Open `src/docs/components/[name].astro` to see required HTML and CSS classes. (Component docs live under `src/docs/components/` now; `src/pages/components/` only contains route shells.)
|
|
243
|
+
2. **Analyze the API**: Check `src/component-api/[name]/` (`Astro.astro` and `HTML.astro`) or `src/component-api/[name]-api.astro` for the documented props.
|
|
244
|
+
3. **Implement**: Follow the checklist in Section 0.
|
|
245
|
+
4. **Verify**: Check that your implementation matches the "HTML" preview in the rendered `Example` for the spec page (`/components/[name]`). For framework-specific behaviour, also verify the Astro variant at `/astro/components/[name]`.
|
|
246
|
+
|
|
247
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
type Props = {
|
|
3
|
+
class?: string
|
|
4
|
+
name?: string
|
|
5
|
+
open?: boolean
|
|
6
|
+
variant?: "default" | "outlined" | "elevated" | "tonal"
|
|
7
|
+
[key: string]: any
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const title = "Accordion"
|
|
11
|
+
|
|
12
|
+
const { $id } = Astro.locals
|
|
13
|
+
const { class: className, name, open, variant, ...rest } = Astro.props
|
|
14
|
+
|
|
15
|
+
const summaryId = $id("summary")
|
|
16
|
+
const contentId = $id("content")
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
<details
|
|
20
|
+
name={name}
|
|
21
|
+
class:list={["accordion", "card", variant, className]}
|
|
22
|
+
open={open}
|
|
23
|
+
{...rest}
|
|
24
|
+
>
|
|
25
|
+
<!-- Summary -->
|
|
26
|
+
<!-- prettier-ignore -->
|
|
27
|
+
<summary id={summaryId} aria-controls={contentId}><slot name="summary" /><slot name="marker" /></summary>
|
|
28
|
+
|
|
29
|
+
<!-- Content -->
|
|
30
|
+
<div id={contentId} class="content" role="region" aria-labelledby={summaryId}>
|
|
31
|
+
<slot />
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<!-- Actions -->
|
|
35
|
+
{
|
|
36
|
+
Astro.slots.has("actions") && (
|
|
37
|
+
<div class="actions">
|
|
38
|
+
<slot name="actions" />
|
|
39
|
+
</div>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
</details>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
type Props = {
|
|
3
|
+
[key: string]: any
|
|
4
|
+
alignment?: string
|
|
5
|
+
class?: string
|
|
6
|
+
id?: string
|
|
7
|
+
trigger?: "always" | "hover"
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const title = "Anchor"
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
alignment,
|
|
14
|
+
class: className,
|
|
15
|
+
id: idProp,
|
|
16
|
+
trigger = "always",
|
|
17
|
+
...rest
|
|
18
|
+
} = Astro.props
|
|
19
|
+
|
|
20
|
+
const isHover = trigger === "hover"
|
|
21
|
+
const id = isHover ? (idProp ?? Astro.locals.$id("anchor")) : undefined
|
|
22
|
+
|
|
23
|
+
const insetMap: Record<string, string> = {
|
|
24
|
+
"start start": "auto 100% 100% auto",
|
|
25
|
+
"start end": "auto auto 100% 100%",
|
|
26
|
+
"end start": "100% 100% auto auto",
|
|
27
|
+
"end end": "100% auto auto 100%",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const positionArea = alignment
|
|
31
|
+
? {
|
|
32
|
+
"--anchor-position-area": alignment,
|
|
33
|
+
"--_anchor-inset": insetMap[alignment],
|
|
34
|
+
}
|
|
35
|
+
: {}
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
<span class:list={["anchor", className]} style={positionArea} {...rest}>
|
|
39
|
+
{
|
|
40
|
+
isHover ? (
|
|
41
|
+
<span {...({ interestfor: id } as any)}>
|
|
42
|
+
<slot />
|
|
43
|
+
</span>
|
|
44
|
+
) : (
|
|
45
|
+
<slot />
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
<span class="anchor-floating" id={id} popover={isHover ? "hint" : undefined}>
|
|
49
|
+
<slot name="anchored" />
|
|
50
|
+
</span>
|
|
51
|
+
</span>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
type Props = {
|
|
3
|
+
[key: string]: any
|
|
4
|
+
alt?: string
|
|
5
|
+
as?: "div" | "a" | "button" | string
|
|
6
|
+
class?: string
|
|
7
|
+
href?: string
|
|
8
|
+
isGroup?: boolean
|
|
9
|
+
spacing?: "small" | "x-small"
|
|
10
|
+
src?: string
|
|
11
|
+
variant?: "squared" | "rounded" | "squircle"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const title = "Avatar"
|
|
15
|
+
|
|
16
|
+
const {
|
|
17
|
+
alt,
|
|
18
|
+
as,
|
|
19
|
+
class: className,
|
|
20
|
+
href,
|
|
21
|
+
isGroup,
|
|
22
|
+
spacing,
|
|
23
|
+
src,
|
|
24
|
+
variant,
|
|
25
|
+
...rest
|
|
26
|
+
} = Astro.props
|
|
27
|
+
|
|
28
|
+
const Tag = as || (href ? "a" : "div")
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
<!-- prettier-ignore -->
|
|
32
|
+
<Tag
|
|
33
|
+
class:list={[
|
|
34
|
+
{ avatar: !isGroup },
|
|
35
|
+
!isGroup && variant,
|
|
36
|
+
{
|
|
37
|
+
"gap-small": isGroup && spacing === "small",
|
|
38
|
+
"gap-x-small": isGroup && spacing === "x-small",
|
|
39
|
+
},
|
|
40
|
+
className,
|
|
41
|
+
]}
|
|
42
|
+
href={href}
|
|
43
|
+
role={isGroup ? "group" : undefined}
|
|
44
|
+
{...rest}>{src ? <img src={src} alt={alt} /> : <slot />}</Tag>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Anchor from "../Anchor/Anchor.astro"
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
[key: string]: any
|
|
6
|
+
alignment?: "start-start" | "end-start" | "end-end"
|
|
7
|
+
class?: string
|
|
8
|
+
color?: "critical" | "info" | "neutral" | "success" | "warning"
|
|
9
|
+
dot?: boolean
|
|
10
|
+
invisible?: boolean
|
|
11
|
+
label?: string | number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const title = "Badge"
|
|
15
|
+
|
|
16
|
+
const {
|
|
17
|
+
alignment,
|
|
18
|
+
class: className,
|
|
19
|
+
color,
|
|
20
|
+
dot,
|
|
21
|
+
invisible,
|
|
22
|
+
label,
|
|
23
|
+
...rest
|
|
24
|
+
} = Astro.props
|
|
25
|
+
|
|
26
|
+
const positionArea =
|
|
27
|
+
alignment === "start-start"
|
|
28
|
+
? "start start"
|
|
29
|
+
: alignment === "end-start"
|
|
30
|
+
? "end start"
|
|
31
|
+
: alignment === "end-end"
|
|
32
|
+
? "end end"
|
|
33
|
+
: undefined
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
<Anchor
|
|
37
|
+
alignment={positionArea}
|
|
38
|
+
class:list={[
|
|
39
|
+
"badge",
|
|
40
|
+
{
|
|
41
|
+
dot,
|
|
42
|
+
invisible,
|
|
43
|
+
},
|
|
44
|
+
alignment,
|
|
45
|
+
className,
|
|
46
|
+
color,
|
|
47
|
+
]}
|
|
48
|
+
{...rest}
|
|
49
|
+
>
|
|
50
|
+
<slot />
|
|
51
|
+
<span class="badge-indicator" slot="anchored" aria-label={label?.toString()}
|
|
52
|
+
>{dot ? "" : label}</span
|
|
53
|
+
>
|
|
54
|
+
</Anchor>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
type CommonProps = {
|
|
3
|
+
[key: string]: any
|
|
4
|
+
as?: string
|
|
5
|
+
class?: string
|
|
6
|
+
color?: "critical" | "primary"
|
|
7
|
+
size?: "x-small" | "small" | "large"
|
|
8
|
+
variant?: "outlined" | "tonal" | "filled"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type AnchorProps = CommonProps & {
|
|
12
|
+
disabled?: never
|
|
13
|
+
href: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type ButtonProps = CommonProps & {
|
|
17
|
+
disabled?: boolean
|
|
18
|
+
href?: undefined
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type Props = AnchorProps | ButtonProps
|
|
22
|
+
|
|
23
|
+
export const title = "Button"
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
as,
|
|
27
|
+
class: className,
|
|
28
|
+
color,
|
|
29
|
+
disabled,
|
|
30
|
+
href,
|
|
31
|
+
size,
|
|
32
|
+
variant,
|
|
33
|
+
...rest
|
|
34
|
+
} = Astro.props
|
|
35
|
+
|
|
36
|
+
const Tag = as || (href ? "a" : "button")
|
|
37
|
+
const isButton = Tag === "button"
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
<!-- prettier-ignore -->
|
|
41
|
+
<Tag
|
|
42
|
+
class:list={["button", { disabled: isButton && disabled }, size, variant, color, className]}
|
|
43
|
+
disabled={isButton ? disabled : undefined}
|
|
44
|
+
href={href}
|
|
45
|
+
{...rest}><slot /></Tag>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
type Props = {
|
|
3
|
+
[key: string]: any
|
|
4
|
+
class?: string
|
|
5
|
+
color?: "critical" | "primary"
|
|
6
|
+
orientation?: "vertical"
|
|
7
|
+
size?: "small" | "large"
|
|
8
|
+
variant?: "outlined" | "tonal" | "filled"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const title = "Button Group"
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
class: className,
|
|
15
|
+
color,
|
|
16
|
+
orientation,
|
|
17
|
+
size,
|
|
18
|
+
variant,
|
|
19
|
+
...rest
|
|
20
|
+
} = Astro.props
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<div
|
|
24
|
+
class:list={["button-group", color, size, variant, orientation, className]}
|
|
25
|
+
role="group"
|
|
26
|
+
{...rest}
|
|
27
|
+
>
|
|
28
|
+
<slot />
|
|
29
|
+
</div>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
type Props = {
|
|
3
|
+
[key: string]: any
|
|
4
|
+
class?: string
|
|
5
|
+
severity?: "critical" | "info" | "neutral" | "success" | "warning"
|
|
6
|
+
variant?: "tonal" | "outlined"
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const title = "Callout"
|
|
10
|
+
|
|
11
|
+
const { class: className, severity, variant, ...rest } = Astro.props
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<article
|
|
15
|
+
role="note"
|
|
16
|
+
class:list={["callout", variant, severity, className]}
|
|
17
|
+
{...rest}
|
|
18
|
+
>
|
|
19
|
+
<slot name="icon">
|
|
20
|
+
{
|
|
21
|
+
severity === "info" && (
|
|
22
|
+
<svg
|
|
23
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
24
|
+
width="32"
|
|
25
|
+
height="32"
|
|
26
|
+
viewBox="0 0 32 32"
|
|
27
|
+
>
|
|
28
|
+
<path
|
|
29
|
+
fill="currentColor"
|
|
30
|
+
d="M16 13a1 1 0 0 1 1 1v9a1 1 0 1 1-2 0v-9a1 1 0 0 1 1-1m0-2a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3M2 16C2 8.268 8.268 2 16 2s14 6.268 14 14s-6.268 14-14 14S2 23.732 2 16M16 4C9.373 4 4 9.373 4 16s5.373 12 12 12s12-5.373 12-12S22.627 4 16 4"
|
|
31
|
+
/>
|
|
32
|
+
</svg>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
{
|
|
36
|
+
severity === "warning" && (
|
|
37
|
+
<svg
|
|
38
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
39
|
+
width="32"
|
|
40
|
+
height="32"
|
|
41
|
+
viewBox="0 0 32 32"
|
|
42
|
+
>
|
|
43
|
+
<path
|
|
44
|
+
fill="currentColor"
|
|
45
|
+
d="M17.25 22a1.25 1.25 0 1 1-2.5 0a1.25 1.25 0 0 1 2.5 0M16 9a1 1 0 0 0-1 1v8a1 1 0 1 0 2 0v-8a1 1 0 0 0-1-1m-3.064-5.191c1.332-2.41 4.796-2.41 6.128 0l10.493 18.999C30.846 25.14 29.158 28 26.494 28H5.507c-2.665 0-4.352-2.86-3.064-5.192zm4.377.967a1.5 1.5 0 0 0-2.626 0L4.194 23.775A1.5 1.5 0 0 0 5.507 26h20.987a1.5 1.5 0 0 0 1.313-2.225z"
|
|
46
|
+
/>
|
|
47
|
+
</svg>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
{
|
|
51
|
+
severity === "critical" && (
|
|
52
|
+
<svg
|
|
53
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
54
|
+
width="32"
|
|
55
|
+
height="32"
|
|
56
|
+
viewBox="0 0 48 48"
|
|
57
|
+
>
|
|
58
|
+
<path
|
|
59
|
+
fill="currentColor"
|
|
60
|
+
d="M24 13c.69 0 1.25.56 1.25 1.25v12.5a1.25 1.25 0 1 1-2.5 0v-12.5c0-.69.56-1.25 1.25-1.25m0 21a2 2 0 1 0 0-4a2 2 0 0 0 0 4M4 24C4 12.954 12.954 4 24 4s20 8.954 20 20s-8.954 20-20 20S4 35.046 4 24M24 6.5C14.335 6.5 6.5 14.335 6.5 24S14.335 41.5 24 41.5S41.5 33.665 41.5 24S33.665 6.5 24 6.5"
|
|
61
|
+
/>
|
|
62
|
+
</svg>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
</slot>
|
|
66
|
+
<div class="content">
|
|
67
|
+
{
|
|
68
|
+
Astro.slots.has("title") && (
|
|
69
|
+
<!-- prettier-ignore -->
|
|
70
|
+
<h3 class="title"><slot name="title" /></h3>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
<slot />
|
|
74
|
+
</div>
|
|
75
|
+
</article>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
type Props = {
|
|
3
|
+
variant?: "text" | "outlined" | "elevated" | "tonal"
|
|
4
|
+
actions?: {
|
|
5
|
+
align?: "end"
|
|
6
|
+
}
|
|
7
|
+
[key: string]: any
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const title = "Card"
|
|
11
|
+
|
|
12
|
+
const { variant, actions, class: className, ...rest } = Astro.props
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<div class:list={["card", variant, className]} {...rest}>
|
|
16
|
+
{
|
|
17
|
+
Astro.slots.has("header") && (
|
|
18
|
+
<hgroup>
|
|
19
|
+
<slot name="header" />
|
|
20
|
+
</hgroup>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
{
|
|
24
|
+
Astro.slots.has("content") && (
|
|
25
|
+
<div class="content">
|
|
26
|
+
<slot name="content" />
|
|
27
|
+
</div>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
<slot />
|
|
31
|
+
{
|
|
32
|
+
Astro.slots.has("actions") && (
|
|
33
|
+
<div class:list={["actions", actions?.align && `align-${actions.align}`]}>
|
|
34
|
+
<slot name="actions" />
|
|
35
|
+
</div>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
</div>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
import CheckboxInput from "./CheckboxInput.astro"
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
[key: string]: any
|
|
6
|
+
checked?: boolean
|
|
7
|
+
class?: string
|
|
8
|
+
critical?: boolean
|
|
9
|
+
disabled?: boolean
|
|
10
|
+
hideLabel?: boolean
|
|
11
|
+
id?: string
|
|
12
|
+
indeterminate?: boolean
|
|
13
|
+
name?: string
|
|
14
|
+
required?: boolean
|
|
15
|
+
size?: "small" | "large"
|
|
16
|
+
spread?: boolean
|
|
17
|
+
stack?: boolean
|
|
18
|
+
value?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const title = "Checkbox"
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
checked,
|
|
25
|
+
class: className,
|
|
26
|
+
critical,
|
|
27
|
+
disabled,
|
|
28
|
+
hideLabel,
|
|
29
|
+
id,
|
|
30
|
+
indeterminate,
|
|
31
|
+
name,
|
|
32
|
+
required,
|
|
33
|
+
size,
|
|
34
|
+
spread,
|
|
35
|
+
stack,
|
|
36
|
+
value,
|
|
37
|
+
...rest
|
|
38
|
+
} = Astro.props
|
|
39
|
+
|
|
40
|
+
const { $id, currentFieldName } = Astro.locals
|
|
41
|
+
const endTextId = Astro.slots.has("end-text") ? $id("end-text") : undefined
|
|
42
|
+
|
|
43
|
+
const finalName = name || currentFieldName
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
<label
|
|
47
|
+
class:list={[
|
|
48
|
+
"checkbox",
|
|
49
|
+
size,
|
|
50
|
+
{
|
|
51
|
+
stack,
|
|
52
|
+
spread,
|
|
53
|
+
},
|
|
54
|
+
className,
|
|
55
|
+
]}
|
|
56
|
+
data-invalid={critical || undefined}
|
|
57
|
+
>
|
|
58
|
+
<CheckboxInput
|
|
59
|
+
aria-describedby={endTextId}
|
|
60
|
+
{checked}
|
|
61
|
+
{disabled}
|
|
62
|
+
{id}
|
|
63
|
+
{indeterminate}
|
|
64
|
+
name={finalName}
|
|
65
|
+
{required}
|
|
66
|
+
{value}
|
|
67
|
+
{...rest}
|
|
68
|
+
/>
|
|
69
|
+
<!-- prettier-ignore --><span class:list={[hideLabel ? "sr-only" : "label"]}><slot /></span>
|
|
70
|
+
{
|
|
71
|
+
Astro.slots.has("end-text") && (
|
|
72
|
+
<!-- prettier-ignore -->
|
|
73
|
+
<span id={endTextId} class="end-text"><slot name="end-text" /></span>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
</label>
|