@elysn/astro 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/LICENSE +201 -0
- package/index.ts +46 -0
- package/package.json +36 -16
- package/src/AccessibleIcon.astro +14 -0
- package/src/AspectRatio.astro +14 -0
- package/src/Avatar.astro +54 -0
- package/src/Badge.astro +34 -0
- package/src/Blockquote.astro +21 -0
- package/src/Box.astro +13 -0
- package/src/Button.astro +27 -8
- package/src/Callout.astro +34 -0
- package/src/CalloutIcon.astro +12 -0
- package/src/CalloutText.astro +12 -0
- package/src/Card.astro +30 -0
- package/src/Checkbox.astro +212 -0
- package/src/Code.astro +21 -0
- package/src/Container.astro +26 -0
- package/src/DecoratedBox.astro +22 -0
- package/src/Em.astro +10 -0
- package/src/Flex.astro +25 -0
- package/src/Grid.astro +21 -0
- package/src/Heading.astro +43 -0
- package/src/InputControl.astro +40 -0
- package/src/InputField.astro +10 -0
- package/src/InputSlot.astro +41 -0
- package/src/Kbd.astro +11 -0
- package/src/Link.astro +33 -0
- package/src/Panel.astro +12 -0
- package/src/Progress.astro +63 -0
- package/src/Quote.astro +10 -0
- package/src/RadioCards.astro +71 -0
- package/src/RadioCardsItem.astro +41 -0
- package/src/RadioGroup.astro +70 -0
- package/src/RadioGroupItem.astro +53 -0
- package/src/Section.astro +23 -0
- package/src/SegmentedControl.astro +189 -0
- package/src/Separator.astro +25 -0
- package/src/Skeleton.astro +30 -0
- package/src/Spinner.astro +31 -0
- package/src/Strong.astro +10 -0
- package/src/Switch.astro +164 -0
- package/src/Tabs.astro +179 -0
- package/src/TabsContent.astro +20 -0
- package/src/TabsIndicator.astro +17 -0
- package/src/TabsList.astro +12 -0
- package/src/TabsTrigger.astro +23 -0
- package/src/Text.astro +43 -0
- package/src/TextArea.astro +30 -0
- package/src/TextField.astro +70 -0
- package/src/VisuallyHidden.astro +10 -0
- package/src/internal/radio-group.ts +82 -0
- package/src/internal/ssr.ts +18 -0
- package/src/internal/zag.ts +24 -0
- package/style.css +5 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
type Size = "xs" | "sm" | "md" | "lg";
|
|
5
|
+
|
|
6
|
+
interface Props extends Omit<HTMLAttributes<"label">, "color" | "dir" | "name"> {
|
|
7
|
+
className?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
defaultChecked?: boolean | "indeterminate";
|
|
10
|
+
dir?: "ltr" | "rtl";
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
highContrast?: boolean;
|
|
13
|
+
invalid?: boolean;
|
|
14
|
+
name?: string;
|
|
15
|
+
radius?: "none" | "small" | "medium" | "large" | "full";
|
|
16
|
+
required?: boolean;
|
|
17
|
+
size?: Size;
|
|
18
|
+
value?: string;
|
|
19
|
+
variant?: "surface" | "soft";
|
|
20
|
+
}
|
|
21
|
+
const {
|
|
22
|
+
className,
|
|
23
|
+
color,
|
|
24
|
+
defaultChecked,
|
|
25
|
+
dir,
|
|
26
|
+
disabled,
|
|
27
|
+
highContrast,
|
|
28
|
+
invalid,
|
|
29
|
+
name,
|
|
30
|
+
radius,
|
|
31
|
+
required,
|
|
32
|
+
size = "md",
|
|
33
|
+
value = "on",
|
|
34
|
+
variant = "surface",
|
|
35
|
+
...rest
|
|
36
|
+
} = Astro.props as Props;
|
|
37
|
+
|
|
38
|
+
const sizes: Record<Size, string> = {
|
|
39
|
+
xs: "el-Checkbox-size-xs",
|
|
40
|
+
sm: "el-Checkbox-size-sm",
|
|
41
|
+
md: "el-Checkbox-size-md",
|
|
42
|
+
lg: "el-Checkbox-size-lg",
|
|
43
|
+
};
|
|
44
|
+
const indeterminate = defaultChecked === "indeterminate";
|
|
45
|
+
const checked = defaultChecked === true;
|
|
46
|
+
const state = indeterminate ? "indeterminate" : checked ? "checked" : "unchecked";
|
|
47
|
+
const hasLabel = Astro.slots.has("default");
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
<!-- display: contents keeps the Zag root (a <label>) as the visual box -->
|
|
51
|
+
<el-checkbox
|
|
52
|
+
style="display: contents"
|
|
53
|
+
data-default-checked={defaultChecked === undefined ? undefined : String(defaultChecked)}
|
|
54
|
+
data-dir={dir}
|
|
55
|
+
>
|
|
56
|
+
<label
|
|
57
|
+
{...rest}
|
|
58
|
+
data-scope="checkbox"
|
|
59
|
+
data-part="root"
|
|
60
|
+
data-state={state}
|
|
61
|
+
data-disabled={disabled ? "" : undefined}
|
|
62
|
+
data-invalid={invalid ? "" : undefined}
|
|
63
|
+
data-accent-color={color}
|
|
64
|
+
data-high-contrast={highContrast ? "true" : undefined}
|
|
65
|
+
data-radius={radius}
|
|
66
|
+
data-variant={variant}
|
|
67
|
+
class:list={["el-Checkbox", sizes[size], className]}
|
|
68
|
+
>
|
|
69
|
+
<div data-scope="checkbox" data-part="control" data-state={state} class="el-Checkbox-control">
|
|
70
|
+
<div
|
|
71
|
+
data-scope="checkbox"
|
|
72
|
+
data-part="indicator"
|
|
73
|
+
data-indicator="checked"
|
|
74
|
+
data-state={state}
|
|
75
|
+
hidden={!checked}
|
|
76
|
+
>
|
|
77
|
+
<svg
|
|
78
|
+
fill="none"
|
|
79
|
+
height="10"
|
|
80
|
+
stroke="currentColor"
|
|
81
|
+
stroke-width="2.5"
|
|
82
|
+
viewBox="0 0 14 14"
|
|
83
|
+
width="10"
|
|
84
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
85
|
+
>
|
|
86
|
+
<path d="M2 7L5.5 10.5L12 3" stroke-linecap="round" stroke-linejoin="round"></path>
|
|
87
|
+
</svg>
|
|
88
|
+
</div>
|
|
89
|
+
<div
|
|
90
|
+
data-scope="checkbox"
|
|
91
|
+
data-part="indicator"
|
|
92
|
+
data-indicator="indeterminate"
|
|
93
|
+
data-state={state}
|
|
94
|
+
hidden={!indeterminate}
|
|
95
|
+
>
|
|
96
|
+
<svg
|
|
97
|
+
fill="none"
|
|
98
|
+
height="10"
|
|
99
|
+
stroke="currentColor"
|
|
100
|
+
stroke-width="2.5"
|
|
101
|
+
viewBox="0 0 14 14"
|
|
102
|
+
width="10"
|
|
103
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
104
|
+
>
|
|
105
|
+
<path d="M2 7H12" stroke-linecap="round"></path>
|
|
106
|
+
</svg>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
{
|
|
110
|
+
hasLabel && (
|
|
111
|
+
<span data-scope="checkbox" data-part="label" data-state={state} class="el-Checkbox-label">
|
|
112
|
+
<slot />
|
|
113
|
+
</span>
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
<input
|
|
117
|
+
type="checkbox"
|
|
118
|
+
data-part="hidden-input"
|
|
119
|
+
name={name}
|
|
120
|
+
value={value}
|
|
121
|
+
checked={checked}
|
|
122
|
+
disabled={disabled}
|
|
123
|
+
required={required}
|
|
124
|
+
style="border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap;word-wrap:normal"
|
|
125
|
+
/>
|
|
126
|
+
</label>
|
|
127
|
+
</el-checkbox>
|
|
128
|
+
|
|
129
|
+
<script>
|
|
130
|
+
import * as zcheckbox from "@zag-js/checkbox";
|
|
131
|
+
import { VanillaMachine, normalizeProps } from "@zag-js/vanilla";
|
|
132
|
+
import { createSpreader, nextId, textDirection } from "./internal/zag";
|
|
133
|
+
|
|
134
|
+
type Machine = ReturnType<typeof createMachine>;
|
|
135
|
+
const createMachine = (props: zcheckbox.Props) => new VanillaMachine(zcheckbox.machine, props);
|
|
136
|
+
|
|
137
|
+
class ElCheckbox extends HTMLElement {
|
|
138
|
+
#machine?: Machine;
|
|
139
|
+
#unsubscribe?: () => void;
|
|
140
|
+
#spread = createSpreader("");
|
|
141
|
+
|
|
142
|
+
connectedCallback() {
|
|
143
|
+
if (this.#machine) return;
|
|
144
|
+
const id = nextId("el-checkbox");
|
|
145
|
+
this.#spread = createSpreader(id);
|
|
146
|
+
const input = this.#part("hidden-input") as HTMLInputElement | undefined;
|
|
147
|
+
const initial = this.dataset["defaultChecked"];
|
|
148
|
+
const machine = createMachine({
|
|
149
|
+
id,
|
|
150
|
+
defaultChecked: initial === "indeterminate" ? "indeterminate" : initial === "true",
|
|
151
|
+
disabled: input?.disabled,
|
|
152
|
+
required: input?.required,
|
|
153
|
+
invalid: this.querySelector("[data-invalid]") !== null,
|
|
154
|
+
name: input?.name || undefined,
|
|
155
|
+
value: input?.value,
|
|
156
|
+
dir: textDirection(this),
|
|
157
|
+
getRootNode: () => this.getRootNode(),
|
|
158
|
+
onCheckedChange: ({ checked }: { checked: boolean | "indeterminate" }) =>
|
|
159
|
+
this.dispatchEvent(
|
|
160
|
+
new CustomEvent("el-checkbox:checked-change", { detail: { checked }, bubbles: true }),
|
|
161
|
+
),
|
|
162
|
+
});
|
|
163
|
+
this.#machine = machine;
|
|
164
|
+
machine.start();
|
|
165
|
+
this.#render();
|
|
166
|
+
this.#unsubscribe = machine.subscribe(() => this.#render());
|
|
167
|
+
this.dataset["ready"] = "";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
disconnectedCallback() {
|
|
171
|
+
this.#unsubscribe?.();
|
|
172
|
+
this.#spread.clear();
|
|
173
|
+
this.#machine?.stop();
|
|
174
|
+
this.#machine = undefined;
|
|
175
|
+
delete this.dataset["ready"];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Programmatic API: `el.checked` / `el.checked = "indeterminate"`. */
|
|
179
|
+
get checked() {
|
|
180
|
+
const api = this.#api();
|
|
181
|
+
return api?.indeterminate ? "indeterminate" : (api?.checked ?? false);
|
|
182
|
+
}
|
|
183
|
+
set checked(checked: boolean | "indeterminate") {
|
|
184
|
+
this.#api()?.setChecked(checked);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
#api() {
|
|
188
|
+
return this.#machine && zcheckbox.connect(this.#machine.service, normalizeProps);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
#part(name: string) {
|
|
192
|
+
return this.querySelector<HTMLElement>(`[data-part='${name}']`) ?? undefined;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
#render() {
|
|
196
|
+
const api = this.#api();
|
|
197
|
+
if (!api) return;
|
|
198
|
+
// Zag never looks the root up by id, so keep the author's `id` instead of its generated one
|
|
199
|
+
const { id: _id, ...rootProps } = api.getRootProps();
|
|
200
|
+
this.#spread.apply(this.#part("root"), rootProps);
|
|
201
|
+
this.#spread.apply(this.#part("control"), api.getControlProps());
|
|
202
|
+
this.#spread.apply(this.#part("label"), api.getLabelProps());
|
|
203
|
+
this.#spread.apply(this.#part("hidden-input"), api.getHiddenInputProps());
|
|
204
|
+
for (const el of this.querySelectorAll<HTMLElement>("[data-part='indicator']")) {
|
|
205
|
+
this.#spread.apply(el, api.getIndicatorProps());
|
|
206
|
+
el.hidden = el.dataset["indicator"] === "indeterminate" ? !api.indeterminate : !api.checked;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (!customElements.get("el-checkbox")) customElements.define("el-checkbox", ElCheckbox);
|
|
212
|
+
</script>
|
package/src/Code.astro
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends Omit<HTMLAttributes<"code">, "color"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
color?: string;
|
|
7
|
+
highContrast?: boolean;
|
|
8
|
+
size?: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
|
|
9
|
+
variant?: "solid" | "soft" | "surface";
|
|
10
|
+
}
|
|
11
|
+
const { className, color, highContrast, size, variant = "soft", ...rest } = Astro.props as Props;
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<code
|
|
15
|
+
{...rest}
|
|
16
|
+
data-accent-color={color}
|
|
17
|
+
data-high-contrast={highContrast ? true : undefined}
|
|
18
|
+
data-size={size}
|
|
19
|
+
data-variant={variant}
|
|
20
|
+
class:list={["el-Code", className]}><slot /></code
|
|
21
|
+
>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
type Size = "xs" | "sm" | "md" | "lg" | "xl";
|
|
5
|
+
|
|
6
|
+
interface Props extends Omit<HTMLAttributes<"div">, "color"> {
|
|
7
|
+
className?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
size?: Size;
|
|
10
|
+
}
|
|
11
|
+
const { className, color, size = "xl", ...rest } = Astro.props as Props;
|
|
12
|
+
|
|
13
|
+
const sizes: Record<Size, string> = {
|
|
14
|
+
xs: "el-Container-size-xs",
|
|
15
|
+
sm: "el-Container-size-sm",
|
|
16
|
+
md: "el-Container-size-md",
|
|
17
|
+
lg: "el-Container-size-lg",
|
|
18
|
+
xl: "el-Container-size-xl",
|
|
19
|
+
};
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<div {...rest} data-accent-color={color} class:list={["el-Container", sizes[size], className]}>
|
|
23
|
+
<div class="el-ContainerInner">
|
|
24
|
+
<slot />
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends HTMLAttributes<"div"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
const { className, style, ...rest } = Astro.props as Props;
|
|
8
|
+
|
|
9
|
+
const hatch =
|
|
10
|
+
"url(\"data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%239C92AC' fill-opacity='0.2' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E\")";
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<div
|
|
14
|
+
{...rest}
|
|
15
|
+
class:list={[
|
|
16
|
+
"bg-gray-a3 border-gray-a5 h-full w-full rounded-md border text-center",
|
|
17
|
+
className,
|
|
18
|
+
]}
|
|
19
|
+
style={[`background-image: ${hatch}`, style].filter(Boolean).join(";")}
|
|
20
|
+
>
|
|
21
|
+
<slot />
|
|
22
|
+
</div>
|
package/src/Em.astro
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends HTMLAttributes<"em"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
const { className, ...rest } = Astro.props as Props;
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<em {...rest} class:list={["el-Em", className]}><slot /></em>
|
package/src/Flex.astro
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends HTMLAttributes<"div"> {
|
|
5
|
+
align?: "start" | "center" | "end" | "stretch" | "baseline";
|
|
6
|
+
className?: string;
|
|
7
|
+
direction?: "row" | "column" | "row-reverse" | "column-reverse";
|
|
8
|
+
gap?: "xs" | "sm" | "md" | "lg" | "xl";
|
|
9
|
+
justify?: "start" | "center" | "end" | "between" | "around" | "evenly";
|
|
10
|
+
wrap?: "nowrap" | "wrap" | "wrap-reverse";
|
|
11
|
+
}
|
|
12
|
+
const { align, className, direction, gap, justify, wrap, ...rest } = Astro.props as Props;
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<div
|
|
16
|
+
{...rest}
|
|
17
|
+
data-align={align}
|
|
18
|
+
data-direction={direction}
|
|
19
|
+
data-gap={gap}
|
|
20
|
+
data-justify={justify}
|
|
21
|
+
data-wrap={wrap}
|
|
22
|
+
class:list={["el-Flex", className]}
|
|
23
|
+
>
|
|
24
|
+
<slot />
|
|
25
|
+
</div>
|
package/src/Grid.astro
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends Omit<HTMLAttributes<"div">, "style"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
columns?: string;
|
|
7
|
+
gap?: "xs" | "sm" | "md" | "lg" | "xl";
|
|
8
|
+
style?: Record<string, string | number>;
|
|
9
|
+
}
|
|
10
|
+
const { className, columns, gap, style, ...rest } = Astro.props as Props;
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<div
|
|
14
|
+
{...rest}
|
|
15
|
+
data-columns={columns}
|
|
16
|
+
data-gap={gap}
|
|
17
|
+
class:list={["el-Grid", className]}
|
|
18
|
+
style={columns ? { gridTemplateColumns: columns, ...style } : style}
|
|
19
|
+
>
|
|
20
|
+
<slot />
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends Omit<HTMLAttributes<"h2">, "color"> {
|
|
5
|
+
align?: "left" | "center" | "right";
|
|
6
|
+
as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
7
|
+
className?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
highContrast?: boolean;
|
|
10
|
+
size?: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
|
|
11
|
+
trim?: "normal" | "start" | "end" | "both";
|
|
12
|
+
truncate?: boolean;
|
|
13
|
+
weight?: "light" | "regular" | "medium" | "bold";
|
|
14
|
+
wrap?: "normal" | "nowrap" | "pretty" | "balance";
|
|
15
|
+
}
|
|
16
|
+
const {
|
|
17
|
+
align,
|
|
18
|
+
as: Tag = "h2",
|
|
19
|
+
className,
|
|
20
|
+
color,
|
|
21
|
+
highContrast,
|
|
22
|
+
size,
|
|
23
|
+
trim,
|
|
24
|
+
truncate,
|
|
25
|
+
weight,
|
|
26
|
+
wrap,
|
|
27
|
+
...rest
|
|
28
|
+
} = Astro.props as Props;
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
<Tag
|
|
32
|
+
{...rest}
|
|
33
|
+
data-accent-color={color}
|
|
34
|
+
data-align={align}
|
|
35
|
+
data-high-contrast={highContrast ? true : undefined}
|
|
36
|
+
data-size={size}
|
|
37
|
+
data-trim={trim}
|
|
38
|
+
data-weight={weight}
|
|
39
|
+
data-wrap={wrap}
|
|
40
|
+
class:list={["el-Heading", truncate && "el-Heading-truncate", className]}
|
|
41
|
+
>
|
|
42
|
+
<slot />
|
|
43
|
+
</Tag>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends Omit<HTMLAttributes<"div">, "color"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
color?: string;
|
|
7
|
+
/** Defaults to the surrounding `TextField` variant, else surface. */
|
|
8
|
+
variant?: "surface" | "soft";
|
|
9
|
+
}
|
|
10
|
+
const { className, color, variant, ...rest } = Astro.props as Props;
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<div
|
|
14
|
+
{...rest}
|
|
15
|
+
data-accent-color={color}
|
|
16
|
+
data-variant={variant}
|
|
17
|
+
class:list={["el-InputControl", className]}
|
|
18
|
+
>
|
|
19
|
+
<slot />
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<script>
|
|
23
|
+
// Clicking a slot (not the input, a button or a link) focuses the input, like the React InputControl
|
|
24
|
+
const rightSlot =
|
|
25
|
+
".el-InputSlot[data-side='right'], .el-InputSlot:not([data-side='right']) ~ .el-InputSlot:not([data-side='left'])";
|
|
26
|
+
document.addEventListener("pointerdown", (event) => {
|
|
27
|
+
const target = event.target;
|
|
28
|
+
if (!(target instanceof Element) || target.closest("input, button, a")) return;
|
|
29
|
+
const control = target.closest(".el-InputControl");
|
|
30
|
+
const input = control?.querySelector<HTMLInputElement>(".el-InputField");
|
|
31
|
+
if (!input || event.defaultPrevented) return;
|
|
32
|
+
const position = target.closest(rightSlot) ? input.value.length : 0;
|
|
33
|
+
requestAnimationFrame(() => {
|
|
34
|
+
try {
|
|
35
|
+
input.setSelectionRange(position, position);
|
|
36
|
+
} catch {}
|
|
37
|
+
input.focus();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
</script>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends HTMLAttributes<"input"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
const { className, ...rest } = Astro.props as Props;
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<input {...rest} class:list={["el-InputField", className]} />
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
type Space = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
|
|
5
|
+
|
|
6
|
+
interface Props extends Omit<HTMLAttributes<"div">, "color" | "style"> {
|
|
7
|
+
className?: string;
|
|
8
|
+
/** Tints the slot with `--accent-a11`. */
|
|
9
|
+
color?: string;
|
|
10
|
+
/** Defaults to left; two unsided slots land left then right. */
|
|
11
|
+
side?: "left" | "right";
|
|
12
|
+
/** Space scale step (0-9) overriding the size-based defaults. */
|
|
13
|
+
gap?: Space;
|
|
14
|
+
px?: Space;
|
|
15
|
+
pl?: Space;
|
|
16
|
+
pr?: Space;
|
|
17
|
+
style?: string;
|
|
18
|
+
}
|
|
19
|
+
const { className, color, side, gap, px, pl, pr, style, ...rest } = Astro.props as Props;
|
|
20
|
+
|
|
21
|
+
const space = (value?: Space) => (value === undefined ? undefined : `var(--space-${value})`);
|
|
22
|
+
const vars = Object.entries({
|
|
23
|
+
"--slot-gap": space(gap),
|
|
24
|
+
"--slot-px": space(px),
|
|
25
|
+
"--slot-pl": space(pl),
|
|
26
|
+
"--slot-pr": space(pr),
|
|
27
|
+
})
|
|
28
|
+
.filter(([, value]) => value !== undefined)
|
|
29
|
+
.map(([name, value]) => `${name}: ${value}`);
|
|
30
|
+
const css = [...vars, style].filter(Boolean).join("; ") || undefined;
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
<div
|
|
34
|
+
{...rest}
|
|
35
|
+
data-accent-color={color}
|
|
36
|
+
data-side={side}
|
|
37
|
+
style={css}
|
|
38
|
+
class:list={["el-InputSlot", className]}
|
|
39
|
+
>
|
|
40
|
+
<slot />
|
|
41
|
+
</div>
|
package/src/Kbd.astro
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends HTMLAttributes<"kbd"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
size?: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
|
|
7
|
+
}
|
|
8
|
+
const { className, size, ...rest } = Astro.props as Props;
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<kbd {...rest} data-size={size} class:list={["el-Kbd", className]}><slot /></kbd>
|
package/src/Link.astro
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends Omit<HTMLAttributes<"a">, "color"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
color?: string;
|
|
7
|
+
highContrast?: boolean;
|
|
8
|
+
size?: "xs" | "sm" | "md" | "lg" | "xl";
|
|
9
|
+
truncate?: boolean;
|
|
10
|
+
underline?: "auto" | "always" | "hover" | "none";
|
|
11
|
+
variant?: "soft" | "surface" | "outline";
|
|
12
|
+
}
|
|
13
|
+
const {
|
|
14
|
+
className,
|
|
15
|
+
color,
|
|
16
|
+
highContrast,
|
|
17
|
+
size,
|
|
18
|
+
truncate,
|
|
19
|
+
underline = "auto",
|
|
20
|
+
variant,
|
|
21
|
+
...rest
|
|
22
|
+
} = Astro.props as Props;
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
<a
|
|
26
|
+
{...rest}
|
|
27
|
+
data-accent-color={color}
|
|
28
|
+
data-high-contrast={highContrast ? true : undefined}
|
|
29
|
+
data-size={size}
|
|
30
|
+
data-underline={underline}
|
|
31
|
+
data-variant={variant}
|
|
32
|
+
class:list={["el-Link", truncate && "el-Link-truncate", className]}><slot /></a
|
|
33
|
+
>
|
package/src/Panel.astro
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends HTMLAttributes<"div"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
const { className, ...rest } = Astro.props as Props;
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<div {...rest} class:list={["el-PanelBase", className]}>
|
|
11
|
+
<slot />
|
|
12
|
+
</div>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
type Size = "xs" | "sm" | "md" | "lg";
|
|
5
|
+
|
|
6
|
+
interface Props extends Omit<HTMLAttributes<"div">, "color"> {
|
|
7
|
+
className?: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
highContrast?: boolean;
|
|
10
|
+
max?: number;
|
|
11
|
+
min?: number;
|
|
12
|
+
radius?: "none" | "small" | "medium" | "large" | "full";
|
|
13
|
+
size?: Size;
|
|
14
|
+
/** Omit for an indeterminate progress bar */
|
|
15
|
+
value?: number;
|
|
16
|
+
variant?: "soft" | "surface";
|
|
17
|
+
}
|
|
18
|
+
const {
|
|
19
|
+
className,
|
|
20
|
+
color,
|
|
21
|
+
highContrast,
|
|
22
|
+
max = 100,
|
|
23
|
+
min = 0,
|
|
24
|
+
radius,
|
|
25
|
+
size = "md",
|
|
26
|
+
value,
|
|
27
|
+
variant = "surface",
|
|
28
|
+
...rest
|
|
29
|
+
} = Astro.props as Props;
|
|
30
|
+
|
|
31
|
+
const sizes: Record<Size, string> = {
|
|
32
|
+
xs: "el-Progress-size-xs",
|
|
33
|
+
sm: "el-Progress-size-sm",
|
|
34
|
+
md: "el-Progress-size-md",
|
|
35
|
+
lg: "el-Progress-size-lg",
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const indeterminate = value === undefined;
|
|
39
|
+
const percent = indeterminate ? undefined : ((value - min) / (max - min)) * 100;
|
|
40
|
+
const state = indeterminate ? "indeterminate" : value >= max ? "complete" : "loading";
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
<div
|
|
44
|
+
{...rest}
|
|
45
|
+
role="progressbar"
|
|
46
|
+
aria-valuemin={min}
|
|
47
|
+
aria-valuemax={max}
|
|
48
|
+
aria-valuenow={value}
|
|
49
|
+
data-accent-color={color}
|
|
50
|
+
data-high-contrast={highContrast ? "true" : undefined}
|
|
51
|
+
data-state={state}
|
|
52
|
+
data-variant={variant}
|
|
53
|
+
class:list={["el-Progress", sizes[size], className]}
|
|
54
|
+
>
|
|
55
|
+
<div class="el-Progress-track" data-radius={radius}>
|
|
56
|
+
<div
|
|
57
|
+
class="el-Progress-range"
|
|
58
|
+
data-state={state}
|
|
59
|
+
style={percent === undefined ? undefined : { width: `${percent}%` }}
|
|
60
|
+
>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
package/src/Quote.astro
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
|
|
4
|
+
interface Props extends HTMLAttributes<"q"> {
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
const { className, ...rest } = Astro.props as Props;
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<q {...rest} class:list={["el-Quote", className]}><slot /></q>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
import { markChecked } from "./internal/ssr";
|
|
4
|
+
|
|
5
|
+
type Size = "xs" | "sm" | "md";
|
|
6
|
+
|
|
7
|
+
interface Props extends Omit<HTMLAttributes<"div">, "color" | "dir" | "name"> {
|
|
8
|
+
className?: string;
|
|
9
|
+
color?: string;
|
|
10
|
+
defaultValue?: string;
|
|
11
|
+
dir?: "ltr" | "rtl";
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
highContrast?: boolean;
|
|
14
|
+
name?: string;
|
|
15
|
+
orientation?: "horizontal" | "vertical";
|
|
16
|
+
radius?: "none" | "small" | "medium" | "large" | "full";
|
|
17
|
+
required?: boolean;
|
|
18
|
+
size?: Size;
|
|
19
|
+
variant?: "surface";
|
|
20
|
+
}
|
|
21
|
+
const {
|
|
22
|
+
className,
|
|
23
|
+
color,
|
|
24
|
+
defaultValue,
|
|
25
|
+
dir,
|
|
26
|
+
disabled,
|
|
27
|
+
highContrast,
|
|
28
|
+
name,
|
|
29
|
+
orientation = "vertical",
|
|
30
|
+
radius,
|
|
31
|
+
required,
|
|
32
|
+
size = "sm",
|
|
33
|
+
variant = "surface",
|
|
34
|
+
...rest
|
|
35
|
+
} = Astro.props as Props;
|
|
36
|
+
|
|
37
|
+
const sizes: Record<Size, string> = {
|
|
38
|
+
xs: "el-RadioCards-size-xs",
|
|
39
|
+
sm: "el-RadioCards-size-sm",
|
|
40
|
+
md: "el-RadioCards-size-md",
|
|
41
|
+
};
|
|
42
|
+
const items = markChecked(await Astro.slots.render("default"), defaultValue);
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
<!-- Same Zag radio-group machine as RadioGroup: the custom element is shared -->
|
|
46
|
+
<el-radio-group
|
|
47
|
+
{...rest}
|
|
48
|
+
role="radiogroup"
|
|
49
|
+
data-scope="radio-group"
|
|
50
|
+
data-part="root"
|
|
51
|
+
data-slot="control"
|
|
52
|
+
data-accent-color={color}
|
|
53
|
+
data-default-value={defaultValue}
|
|
54
|
+
data-dir={dir}
|
|
55
|
+
data-disabled={disabled ? "" : undefined}
|
|
56
|
+
data-high-contrast={highContrast ? "true" : undefined}
|
|
57
|
+
data-name={name}
|
|
58
|
+
data-orientation={orientation}
|
|
59
|
+
data-radius={radius}
|
|
60
|
+
data-required={required ? "true" : undefined}
|
|
61
|
+
data-variant={variant}
|
|
62
|
+
class:list={["el-RadioCardsRoot", sizes[size], className]}
|
|
63
|
+
>
|
|
64
|
+
<Fragment set:html={items} />
|
|
65
|
+
</el-radio-group>
|
|
66
|
+
|
|
67
|
+
<script>
|
|
68
|
+
import { defineRadioGroup } from "./internal/radio-group";
|
|
69
|
+
|
|
70
|
+
defineRadioGroup();
|
|
71
|
+
</script>
|