@jirawatpyk/aura-tokens 4.16.0 → 4.18.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/README.md +15 -11
- package/aura-tailwind.css +1 -1
- package/aura-tailwind.prefixed.css +165 -0
- package/aura.css +1 -1
- package/components/aura.bundle.js +202 -126
- package/components/aura.components.css +22 -4
- package/components/index.d.ts +33 -7
- package/package.json +4 -2
- package/tokens.json +1 -1
package/README.md
CHANGED
|
@@ -29,20 +29,12 @@ npm install @aura/tokens@npm:@jirawatpyk/aura-tokens @aura/react@npm:@jirawatpyk
|
|
|
29
29
|
|
|
30
30
|
```tsx
|
|
31
31
|
// app/layout.tsx
|
|
32
|
-
import '@aura/tokens/aura-fonts.css'; //
|
|
32
|
+
import '@aura/tokens/aura-fonts.local.css'; // fonts, self-hosted from the package: works under a font-src 'self' CSP
|
|
33
33
|
import '@aura/tokens/aura.css'; // tokens
|
|
34
34
|
import '@aura/react/styles.css'; // component styles (with @aura/react)
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
<!-- Preferred: load the fonts from <head> instead of aura-fonts.css — faster, and a blocked host fails quietly -->
|
|
39
|
-
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
40
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
41
|
-
<link
|
|
42
|
-
rel="stylesheet"
|
|
43
|
-
href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,600&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400&family=Noto+Sans+Thai:wght@400;500;600&display=swap"
|
|
44
|
-
/>
|
|
45
|
-
```
|
|
37
|
+
Next.js can load the same families with `next/font` instead, and a site with no CSP can use Google Fonts (`aura-fonts.css` or `<link>` tags). Both are under Fonts below.
|
|
46
38
|
|
|
47
39
|
### Fonts
|
|
48
40
|
|
|
@@ -52,7 +44,17 @@ Pick one of three ways to load Fraunces, Inter, JetBrains Mono and Noto Sans Tha
|
|
|
52
44
|
| ------------------ | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
53
45
|
| Self-hosted (4.16) | Your CSP allows only `font-src 'self'`, or you want no third-party requests | `import '@jirawatpyk/aura-tokens/aura-fonts.local.css'` — woff2 files ship in the package (`fonts/`, OFL-1.1), split by unicode range so a page downloads only what it uses |
|
|
54
46
|
| `next/font` | Next.js apps that want preloading and zero layout shift | Load the families with `next/font` and point the AURA font variables at them (below) |
|
|
55
|
-
| Google Fonts |
|
|
47
|
+
| Google Fonts | No CSP, or one that allows `fonts.googleapis.com` and `fonts.gstatic.com` | `aura-fonts.css`, or the `<link>` tags below (faster; a blocked host fails quietly) |
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<!-- Google Fonts from <head> (only without a strict CSP) -->
|
|
51
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
52
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
53
|
+
<link
|
|
54
|
+
rel="stylesheet"
|
|
55
|
+
href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,600&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400&family=Noto+Sans+Thai:wght@400;500;600&display=swap"
|
|
56
|
+
/>
|
|
57
|
+
```
|
|
56
58
|
|
|
57
59
|
```tsx
|
|
58
60
|
// app/layout.tsx — next/font (downloads at build time and self-hosts, so font-src 'self' is enough)
|
|
@@ -86,6 +88,8 @@ Dark theme: put `class="dark"` (or `data-theme="dark"`) on `<html>`.
|
|
|
86
88
|
|
|
87
89
|
Classes: `bg-bg-surface`, `text-fg-primary`, `border-border-strong`, `text-fg-danger`, `bg-alert-warning-bg`, `fill-chart-1`, `p-aura-6`, `gap-aura-4`, `rounded-aura-xl`, `shadow-aura-overlay`, `ease-aura-ease`, `duration-aura-fast`, `z-aura-dialog`, `font-display` / `font-sans` / `font-mono`. They point at the `--aura-*` variables, so `.dark` or `data-theme="dark"` switches them with no `dark:` prefix; the file also makes `dark:` follow those two switches. `npm run check:tailwind4` compiles it with Tailwind v4 in CI.
|
|
88
90
|
|
|
91
|
+
Next to an existing Tailwind theme (shadcn) use `@jirawatpyk/aura-tokens/tailwind.prefixed.css` instead (4.17). Every name carries `aura-` (`bg-aura-bg-surface`, `border-aura-border-strong`, `bg-aura-chart-1`, `font-aura-sans`), with no `@custom-variant` and no `@import`. Import `aura.css` yourself in an early layer so your theme keeps its `--font-*`. The React package README has the full setup, with `@jirawatpyk/aura-react/styles.layer.css`.
|
|
92
|
+
|
|
89
93
|
### Tailwind v3
|
|
90
94
|
|
|
91
95
|
```ts
|
package/aura-tailwind.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* AURA v4.
|
|
1
|
+
/* AURA v4.18.0 — Tailwind v4 theme. GENERATED by scripts/build-tokens.js from tokens.json. Do not edit by hand.
|
|
2
2
|
* @import "tailwindcss";
|
|
3
3
|
* @import "@jirawatpyk/aura-tokens/tailwind.css";
|
|
4
4
|
* Gives bg-bg-surface, text-fg-primary, border-border-strong, p-aura-6, rounded-aura-xl, shadow-aura-overlay,
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/* AURA v4.18.0 — Tailwind v4 theme with aura- prefixed names. GENERATED by scripts/build-tokens.js. Do not edit by hand.
|
|
2
|
+
* For apps that already have a Tailwind theme (shadcn): nothing here redefines an existing name.
|
|
3
|
+
* @layer aura-tokens, theme, base, aura, components, utilities;
|
|
4
|
+
* @import "tailwindcss";
|
|
5
|
+
* @import "@jirawatpyk/aura-tokens/aura.css" layer(aura-tokens); <- the --aura-* variables; your theme wins for --font-*
|
|
6
|
+
* @import "@jirawatpyk/aura-tokens/tailwind.prefixed.css";
|
|
7
|
+
* @import "@jirawatpyk/aura-react/styles.layer.css"; <- components in @layer aura, so utilities win
|
|
8
|
+
* Classes: bg-aura-bg-surface, text-aura-fg-primary, border-aura-border-strong, bg-aura-chart-1, p-aura-6,
|
|
9
|
+
* rounded-aura-xl, shadow-aura-overlay, font-aura-sans … Use your own dark: variant. */
|
|
10
|
+
|
|
11
|
+
@theme inline {
|
|
12
|
+
--color-aura-violet-50: var(--aura-violet-50);
|
|
13
|
+
--color-aura-violet-100: var(--aura-violet-100);
|
|
14
|
+
--color-aura-violet-200: var(--aura-violet-200);
|
|
15
|
+
--color-aura-violet-300: var(--aura-violet-300);
|
|
16
|
+
--color-aura-violet-400: var(--aura-violet-400);
|
|
17
|
+
--color-aura-violet-500: var(--aura-violet-500);
|
|
18
|
+
--color-aura-violet-600: var(--aura-violet-600);
|
|
19
|
+
--color-aura-violet-700: var(--aura-violet-700);
|
|
20
|
+
--color-aura-violet-800: var(--aura-violet-800);
|
|
21
|
+
--color-aura-violet-900: var(--aura-violet-900);
|
|
22
|
+
--color-aura-zinc-0: var(--aura-zinc-0);
|
|
23
|
+
--color-aura-zinc-50: var(--aura-zinc-50);
|
|
24
|
+
--color-aura-zinc-100: var(--aura-zinc-100);
|
|
25
|
+
--color-aura-zinc-200: var(--aura-zinc-200);
|
|
26
|
+
--color-aura-zinc-300: var(--aura-zinc-300);
|
|
27
|
+
--color-aura-zinc-400: var(--aura-zinc-400);
|
|
28
|
+
--color-aura-zinc-450: var(--aura-zinc-450);
|
|
29
|
+
--color-aura-zinc-500: var(--aura-zinc-500);
|
|
30
|
+
--color-aura-zinc-600: var(--aura-zinc-600);
|
|
31
|
+
--color-aura-zinc-700: var(--aura-zinc-700);
|
|
32
|
+
--color-aura-zinc-800: var(--aura-zinc-800);
|
|
33
|
+
--color-aura-zinc-900: var(--aura-zinc-900);
|
|
34
|
+
--color-aura-zinc-950: var(--aura-zinc-950);
|
|
35
|
+
--color-aura-lime-50: var(--aura-lime-50);
|
|
36
|
+
--color-aura-lime-100: var(--aura-lime-100);
|
|
37
|
+
--color-aura-lime-200: var(--aura-lime-200);
|
|
38
|
+
--color-aura-lime-300: var(--aura-lime-300);
|
|
39
|
+
--color-aura-lime-400: var(--aura-lime-400);
|
|
40
|
+
--color-aura-lime-500: var(--aura-lime-500);
|
|
41
|
+
--color-aura-lime-600: var(--aura-lime-600);
|
|
42
|
+
--color-aura-lime-800: var(--aura-lime-800);
|
|
43
|
+
--color-aura-red-50: var(--aura-red-50);
|
|
44
|
+
--color-aura-red-200: var(--aura-red-200);
|
|
45
|
+
--color-aura-red-300: var(--aura-red-300);
|
|
46
|
+
--color-aura-red-400: var(--aura-red-400);
|
|
47
|
+
--color-aura-red-600: var(--aura-red-600);
|
|
48
|
+
--color-aura-red-700: var(--aura-red-700);
|
|
49
|
+
--color-aura-red-800: var(--aura-red-800);
|
|
50
|
+
--color-aura-amber-50: var(--aura-amber-50);
|
|
51
|
+
--color-aura-amber-200: var(--aura-amber-200);
|
|
52
|
+
--color-aura-amber-300: var(--aura-amber-300);
|
|
53
|
+
--color-aura-amber-800: var(--aura-amber-800);
|
|
54
|
+
--color-aura-ink: var(--aura-ink);
|
|
55
|
+
--color-aura-white: var(--aura-white);
|
|
56
|
+
--color-aura-bg-surface: var(--aura-bg-surface);
|
|
57
|
+
--color-aura-bg-surface-hover: var(--aura-bg-surface-hover);
|
|
58
|
+
--color-aura-bg-surface-strong: var(--aura-bg-surface-strong);
|
|
59
|
+
--color-aura-bg-canvas: var(--aura-bg-canvas);
|
|
60
|
+
--color-aura-bg-inverted: var(--aura-bg-inverted);
|
|
61
|
+
--color-aura-bg-selected: var(--aura-bg-selected);
|
|
62
|
+
--color-aura-bg-skeleton: var(--aura-bg-skeleton);
|
|
63
|
+
--color-aura-bg-input: var(--aura-bg-input);
|
|
64
|
+
--color-aura-bg-input-disabled: var(--aura-bg-input-disabled);
|
|
65
|
+
--color-aura-bg-scrim: var(--aura-bg-scrim);
|
|
66
|
+
--color-aura-bg-hover: var(--aura-bg-surface-hover);
|
|
67
|
+
--color-aura-bg-strong: var(--aura-bg-surface-strong);
|
|
68
|
+
--color-aura-fg-primary: var(--aura-fg-primary);
|
|
69
|
+
--color-aura-fg-secondary: var(--aura-fg-secondary);
|
|
70
|
+
--color-aura-fg-tertiary: var(--aura-fg-tertiary);
|
|
71
|
+
--color-aura-fg-inverted: var(--aura-fg-inverted);
|
|
72
|
+
--color-aura-fg-accent: var(--aura-fg-accent);
|
|
73
|
+
--color-aura-fg-danger: var(--aura-fg-danger);
|
|
74
|
+
--color-aura-fg-positive: var(--aura-fg-positive);
|
|
75
|
+
--color-aura-border: var(--aura-border-default);
|
|
76
|
+
--color-aura-border-default: var(--aura-border-default);
|
|
77
|
+
--color-aura-border-strong: var(--aura-border-strong);
|
|
78
|
+
--color-aura-border-subtle: var(--aura-border-subtle);
|
|
79
|
+
--color-aura-border-control: var(--aura-border-control);
|
|
80
|
+
--color-aura-border-danger: var(--aura-border-danger);
|
|
81
|
+
--color-aura-accent-dot: var(--aura-accent-dot);
|
|
82
|
+
--color-aura-accent-violet: var(--aura-accent-violet);
|
|
83
|
+
--color-aura-accent-lime: var(--aura-accent-lime);
|
|
84
|
+
--color-aura-status-neutral-bg: var(--aura-status-neutral-bg);
|
|
85
|
+
--color-aura-status-neutral-fg: var(--aura-status-neutral-fg);
|
|
86
|
+
--color-aura-status-progress-bg: var(--aura-status-progress-bg);
|
|
87
|
+
--color-aura-status-progress-fg: var(--aura-status-progress-fg);
|
|
88
|
+
--color-aura-status-ready-bg: var(--aura-status-ready-bg);
|
|
89
|
+
--color-aura-status-ready-fg: var(--aura-status-ready-fg);
|
|
90
|
+
--color-aura-status-blocked-bg: var(--aura-status-blocked-bg);
|
|
91
|
+
--color-aura-status-blocked-fg: var(--aura-status-blocked-fg);
|
|
92
|
+
--color-aura-chart-1: var(--aura-chart-1);
|
|
93
|
+
--color-aura-chart-2: var(--aura-chart-2);
|
|
94
|
+
--color-aura-chart-3: var(--aura-chart-3);
|
|
95
|
+
--color-aura-chart-4: var(--aura-chart-4);
|
|
96
|
+
--color-aura-chart-5: var(--aura-chart-5);
|
|
97
|
+
--color-aura-chart-6: var(--aura-chart-6);
|
|
98
|
+
--color-aura-chart-7: var(--aura-chart-7);
|
|
99
|
+
--color-aura-chart-8: var(--aura-chart-8);
|
|
100
|
+
--color-aura-chart-seq-1: var(--aura-chart-seq-1);
|
|
101
|
+
--color-aura-chart-seq-2: var(--aura-chart-seq-2);
|
|
102
|
+
--color-aura-chart-seq-3: var(--aura-chart-seq-3);
|
|
103
|
+
--color-aura-chart-seq-4: var(--aura-chart-seq-4);
|
|
104
|
+
--color-aura-chart-seq-5: var(--aura-chart-seq-5);
|
|
105
|
+
--color-aura-chart-grid: var(--aura-chart-grid);
|
|
106
|
+
--color-aura-chart-axis: var(--aura-chart-axis);
|
|
107
|
+
--color-aura-alert-info-bg: var(--aura-alert-info-bg);
|
|
108
|
+
--color-aura-alert-info-fg: var(--aura-alert-info-fg);
|
|
109
|
+
--color-aura-alert-info-border: var(--aura-alert-info-border);
|
|
110
|
+
--color-aura-alert-success-bg: var(--aura-alert-success-bg);
|
|
111
|
+
--color-aura-alert-success-fg: var(--aura-alert-success-fg);
|
|
112
|
+
--color-aura-alert-success-border: var(--aura-alert-success-border);
|
|
113
|
+
--color-aura-alert-warning-bg: var(--aura-alert-warning-bg);
|
|
114
|
+
--color-aura-alert-warning-fg: var(--aura-alert-warning-fg);
|
|
115
|
+
--color-aura-alert-warning-border: var(--aura-alert-warning-border);
|
|
116
|
+
--color-aura-alert-danger-bg: var(--aura-alert-danger-bg);
|
|
117
|
+
--color-aura-alert-danger-fg: var(--aura-alert-danger-fg);
|
|
118
|
+
--color-aura-alert-danger-border: var(--aura-alert-danger-border);
|
|
119
|
+
--color-aura-focus-ring: var(--aura-focus-ring);
|
|
120
|
+
--spacing-aura-0: var(--aura-space-0);
|
|
121
|
+
--spacing-aura-1: var(--aura-space-1);
|
|
122
|
+
--spacing-aura-2: var(--aura-space-2);
|
|
123
|
+
--spacing-aura-3: var(--aura-space-3);
|
|
124
|
+
--spacing-aura-4: var(--aura-space-4);
|
|
125
|
+
--spacing-aura-5: var(--aura-space-5);
|
|
126
|
+
--spacing-aura-6: var(--aura-space-6);
|
|
127
|
+
--spacing-aura-8: var(--aura-space-8);
|
|
128
|
+
--spacing-aura-10: var(--aura-space-10);
|
|
129
|
+
--spacing-aura-12: var(--aura-space-12);
|
|
130
|
+
--spacing-aura-16: var(--aura-space-16);
|
|
131
|
+
--spacing-aura-card-padding: var(--aura-card-padding);
|
|
132
|
+
--radius-aura-xs: var(--aura-radius-xs);
|
|
133
|
+
--radius-aura-sm: var(--aura-radius-sm);
|
|
134
|
+
--radius-aura-md: var(--aura-radius-md);
|
|
135
|
+
--radius-aura-lg: var(--aura-radius-lg);
|
|
136
|
+
--radius-aura-xl: var(--aura-radius-xl);
|
|
137
|
+
--radius-aura-2xl: var(--aura-radius-2xl);
|
|
138
|
+
--radius-aura-full: var(--aura-radius-full);
|
|
139
|
+
--radius-aura-squircle: var(--aura-radius-squircle);
|
|
140
|
+
--radius-aura-card-radius: var(--aura-card-radius);
|
|
141
|
+
--radius-aura-button-radius: var(--aura-button-radius);
|
|
142
|
+
--shadow-aura-enterprise: var(--aura-shadow-enterprise);
|
|
143
|
+
--shadow-aura-overlay: var(--aura-shadow-overlay);
|
|
144
|
+
--shadow-aura-creative: var(--aura-shadow-creative);
|
|
145
|
+
--shadow-aura-creative-hover: var(--aura-shadow-creative-hover);
|
|
146
|
+
--shadow-aura-card-shadow-creative: var(--aura-card-shadow-creative);
|
|
147
|
+
--ease-aura-ease: var(--aura-ease);
|
|
148
|
+
--ease-aura-spring: var(--aura-spring);
|
|
149
|
+
--font-aura-display: "Fraunces", "Noto Sans Thai", serif;
|
|
150
|
+
--font-aura-sans: "Inter", "Noto Sans Thai", sans-serif;
|
|
151
|
+
--font-aura-mono: "JetBrains Mono", monospace;
|
|
152
|
+
--font-aura-thai: "Noto Sans Thai", sans-serif;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@utility duration-aura-fast { transition-duration: var(--aura-duration-fast); }
|
|
156
|
+
@utility duration-aura-base { transition-duration: var(--aura-duration-base); }
|
|
157
|
+
@utility duration-aura-slow { transition-duration: var(--aura-duration-slow); }
|
|
158
|
+
@utility duration-aura-spin { transition-duration: var(--aura-duration-spin); }
|
|
159
|
+
@utility duration-aura-pulse { transition-duration: var(--aura-duration-pulse); }
|
|
160
|
+
@utility duration-aura-toast { transition-duration: var(--aura-duration-toast); }
|
|
161
|
+
@utility duration-aura-tooltip { transition-duration: var(--aura-duration-tooltip); }
|
|
162
|
+
@utility z-aura-menu { z-index: var(--aura-z-menu); }
|
|
163
|
+
@utility z-aura-dialog { z-index: var(--aura-z-dialog); }
|
|
164
|
+
@utility z-aura-toast { z-index: var(--aura-z-toast); }
|
|
165
|
+
@utility z-aura-tooltip { z-index: var(--aura-z-tooltip); }
|
package/aura.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* AURA v4.
|
|
1
|
+
/* AURA v4.18.0 — GENERATED by scripts/build-tokens.js from tokens.json. Do not edit by hand. */
|
|
2
2
|
/* Fonts: load aura-fonts.css (or the <link> tags in README) separately, so a blocked Google Fonts never breaks this file. */
|
|
3
3
|
|
|
4
4
|
:root, [data-theme="light"] {
|
|
@@ -267,6 +267,8 @@ window.Aura = (() => {
|
|
|
267
267
|
|
|
268
268
|
// src/locale.tsx
|
|
269
269
|
var React3 = __toESM(require_react(), 1);
|
|
270
|
+
|
|
271
|
+
// src/strings.ts
|
|
270
272
|
var n = function(x) {
|
|
271
273
|
return Number(x).toLocaleString("en");
|
|
272
274
|
};
|
|
@@ -614,6 +616,8 @@ window.Aura = (() => {
|
|
|
614
616
|
}
|
|
615
617
|
}
|
|
616
618
|
};
|
|
619
|
+
|
|
620
|
+
// src/locale.tsx
|
|
617
621
|
var LocaleContext = React3.createContext(null);
|
|
618
622
|
function AuraProvider(props) {
|
|
619
623
|
const outer = React3.useContext(LocaleContext);
|
|
@@ -946,12 +950,8 @@ window.Aura = (() => {
|
|
|
946
950
|
|
|
947
951
|
// src/StatusPill.tsx
|
|
948
952
|
var React9 = __toESM(require_react(), 1);
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
progress: "circle-dot-dashed",
|
|
952
|
-
ready: "circle-check",
|
|
953
|
-
blocked: "ban"
|
|
954
|
-
};
|
|
953
|
+
|
|
954
|
+
// src/status.ts
|
|
955
955
|
var TONE_WORDS = {
|
|
956
956
|
ready: ["ready", "done", "complete", "completed", "approved", "live", "passed"],
|
|
957
957
|
progress: ["in progress", "in review", "review", "syncing", "running", "pending"],
|
|
@@ -963,6 +963,14 @@ window.Aura = (() => {
|
|
|
963
963
|
return "neutral";
|
|
964
964
|
}
|
|
965
965
|
var TONE_ORDER = { neutral: 0, progress: 1, ready: 2, blocked: 3 };
|
|
966
|
+
|
|
967
|
+
// src/StatusPill.tsx
|
|
968
|
+
var TONE_ICON = {
|
|
969
|
+
neutral: "circle",
|
|
970
|
+
progress: "circle-dot-dashed",
|
|
971
|
+
ready: "circle-check",
|
|
972
|
+
blocked: "ban"
|
|
973
|
+
};
|
|
966
974
|
var StatusPill = React9.forwardRef(function StatusPill2(props, ref) {
|
|
967
975
|
const tone2 = props.tone || toneFor(props.children);
|
|
968
976
|
return /* @__PURE__ */ React9.createElement("span", { ref, className: cx("aura-pill", "aura-pill--" + tone2, props.className) }, /* @__PURE__ */ React9.createElement(Icon, { name: TONE_ICON[tone2] || "circle", size: 12 }), props.children);
|
|
@@ -1544,6 +1552,8 @@ window.Aura = (() => {
|
|
|
1544
1552
|
// src/DatePicker.tsx
|
|
1545
1553
|
var React17 = __toESM(require_react(), 1);
|
|
1546
1554
|
var import_react_dom3 = __toESM(require_react_dom(), 1);
|
|
1555
|
+
|
|
1556
|
+
// src/dates.ts
|
|
1547
1557
|
var ERA = /^พ\.ศ\.\s?|\s?(BE|พ\.ศ\.)$/g;
|
|
1548
1558
|
var pad = function(n2) {
|
|
1549
1559
|
return (n2 < 10 ? "0" : "") + n2;
|
|
@@ -1649,22 +1659,6 @@ window.Aura = (() => {
|
|
|
1649
1659
|
const loc = o.locale || "th";
|
|
1650
1660
|
return fmt(localeTag(loc, o.calendar || defaultCalendar(loc)), f, d).replace(ERA, "");
|
|
1651
1661
|
}
|
|
1652
|
-
function useFormatDate() {
|
|
1653
|
-
const ctx = useAuraLocale(), locale = ctx.locale || "en", calendar = ctx.calendar;
|
|
1654
|
-
return React17.useCallback(
|
|
1655
|
-
function(iso, opts) {
|
|
1656
|
-
const o = opts || {}, loc = o.locale || locale;
|
|
1657
|
-
return formatDate(
|
|
1658
|
-
iso,
|
|
1659
|
-
Object.assign({}, o, {
|
|
1660
|
-
locale: loc,
|
|
1661
|
-
calendar: o.calendar || (o.locale ? void 0 : calendar) || defaultCalendar(loc)
|
|
1662
|
-
})
|
|
1663
|
-
);
|
|
1664
|
-
},
|
|
1665
|
-
[locale, calendar]
|
|
1666
|
-
);
|
|
1667
|
-
}
|
|
1668
1662
|
var MONTHS = null;
|
|
1669
1663
|
function monthIndex(word) {
|
|
1670
1664
|
if (!MONTHS) {
|
|
@@ -1702,6 +1696,24 @@ window.Aura = (() => {
|
|
|
1702
1696
|
const dt = new Date(y, mo - 1, d);
|
|
1703
1697
|
return dt.getMonth() === mo - 1 && dt.getDate() === d ? toISO(dt) : null;
|
|
1704
1698
|
}
|
|
1699
|
+
|
|
1700
|
+
// src/DatePicker.tsx
|
|
1701
|
+
function useFormatDate() {
|
|
1702
|
+
const ctx = useAuraLocale(), locale = ctx.locale || "en", calendar = ctx.calendar;
|
|
1703
|
+
return React17.useCallback(
|
|
1704
|
+
function(iso, opts) {
|
|
1705
|
+
const o = opts || {}, loc = o.locale || locale;
|
|
1706
|
+
return formatDate(
|
|
1707
|
+
iso,
|
|
1708
|
+
Object.assign({}, o, {
|
|
1709
|
+
locale: loc,
|
|
1710
|
+
calendar: o.calendar || (o.locale ? void 0 : calendar) || defaultCalendar(loc)
|
|
1711
|
+
})
|
|
1712
|
+
);
|
|
1713
|
+
},
|
|
1714
|
+
[locale, calendar]
|
|
1715
|
+
);
|
|
1716
|
+
}
|
|
1705
1717
|
var Calendar = React17.forwardRef(function Calendar2(props, ref) {
|
|
1706
1718
|
const ctx = useAuraLocale(), locale = props.locale || ctx.locale || "en", calendar = props.calendar || ctx.calendar || defaultCalendar(locale), tag = localeTag(locale, calendar);
|
|
1707
1719
|
const weekStart = props.weekStartsOn == null ? locale === "sv" ? 1 : 0 : props.weekStartsOn;
|
|
@@ -2749,7 +2761,12 @@ window.Aura = (() => {
|
|
|
2749
2761
|
const id = uid(), listId = id + "-list";
|
|
2750
2762
|
const box = React25.useRef(null);
|
|
2751
2763
|
const input = React25.useRef(null);
|
|
2752
|
-
const
|
|
2764
|
+
const qState = React25.useState(""), act = React25.useState(null);
|
|
2765
|
+
const query = props.query !== void 0 ? props.query : qState[0];
|
|
2766
|
+
function setQuery(v) {
|
|
2767
|
+
if (props.query === void 0) qState[1](v);
|
|
2768
|
+
if (props.onQueryChange) props.onQueryChange(v);
|
|
2769
|
+
}
|
|
2753
2770
|
const openRef = React25.useRef(props.open);
|
|
2754
2771
|
openRef.current = props.open;
|
|
2755
2772
|
const close = function() {
|
|
@@ -2775,15 +2792,15 @@ window.Aura = (() => {
|
|
|
2775
2792
|
React25.useEffect(
|
|
2776
2793
|
function() {
|
|
2777
2794
|
if (!props.open) {
|
|
2778
|
-
|
|
2779
|
-
act[1](
|
|
2795
|
+
if (query) setQuery("");
|
|
2796
|
+
act[1](null);
|
|
2780
2797
|
}
|
|
2781
2798
|
},
|
|
2782
2799
|
[props.open]
|
|
2783
2800
|
);
|
|
2784
|
-
const filter = props.filter || defaultFilter;
|
|
2801
|
+
const filter = props.filter === false ? null : props.filter || defaultFilter;
|
|
2785
2802
|
const shown = (props.items || []).filter(function(it) {
|
|
2786
|
-
return filter(it,
|
|
2803
|
+
return !filter || filter(it, query);
|
|
2787
2804
|
});
|
|
2788
2805
|
const groups = [];
|
|
2789
2806
|
shown.forEach(function(it) {
|
|
@@ -2805,7 +2822,10 @@ window.Aura = (() => {
|
|
|
2805
2822
|
}).filter(function(i2) {
|
|
2806
2823
|
return i2 >= 0;
|
|
2807
2824
|
});
|
|
2808
|
-
const
|
|
2825
|
+
const byId = act[0] == null ? -1 : flat.findIndex(function(it) {
|
|
2826
|
+
return it.id === act[0];
|
|
2827
|
+
});
|
|
2828
|
+
const active = enabled.indexOf(byId) >= 0 ? byId : enabled.length ? enabled[0] : -1;
|
|
2809
2829
|
const optId = function(i2) {
|
|
2810
2830
|
return id + "-o" + i2;
|
|
2811
2831
|
};
|
|
@@ -2830,7 +2850,7 @@ window.Aura = (() => {
|
|
|
2830
2850
|
if (dir === "first") n2 = 0;
|
|
2831
2851
|
else if (dir === "last") n2 = enabled.length - 1;
|
|
2832
2852
|
else n2 = (at + dir + enabled.length) % enabled.length;
|
|
2833
|
-
act[1](enabled[n2]);
|
|
2853
|
+
act[1](flat[enabled[n2]].id);
|
|
2834
2854
|
}
|
|
2835
2855
|
function onKey(e) {
|
|
2836
2856
|
if (e.key === "ArrowDown") {
|
|
@@ -2881,63 +2901,77 @@ window.Aura = (() => {
|
|
|
2881
2901
|
"data-autofocus": "",
|
|
2882
2902
|
type: "text",
|
|
2883
2903
|
role: "combobox",
|
|
2884
|
-
"aria-expanded":
|
|
2885
|
-
"aria-controls": listId,
|
|
2904
|
+
"aria-expanded": flat.length > 0,
|
|
2905
|
+
"aria-controls": flat.length ? listId : void 0,
|
|
2886
2906
|
"aria-autocomplete": "list",
|
|
2887
2907
|
"aria-activedescendant": active >= 0 ? optId(active) : void 0,
|
|
2888
2908
|
"aria-label": props.label || t.commandMenu,
|
|
2889
2909
|
placeholder: props.placeholder || t.commandPlaceholder,
|
|
2890
2910
|
className: "aura-command__input",
|
|
2891
|
-
value:
|
|
2911
|
+
value: query,
|
|
2892
2912
|
autoComplete: "off",
|
|
2893
2913
|
spellCheck: false,
|
|
2894
2914
|
onChange: function(e) {
|
|
2895
|
-
|
|
2896
|
-
act[1](
|
|
2915
|
+
setQuery(e.target.value);
|
|
2916
|
+
act[1](null);
|
|
2897
2917
|
},
|
|
2898
2918
|
onKeyDown: onKey
|
|
2899
2919
|
}
|
|
2900
2920
|
), /* @__PURE__ */ React25.createElement("kbd", { className: "aura-command__kbd" }, "Esc")),
|
|
2901
|
-
/* @__PURE__ */ React25.createElement("div", { className: "aura-command__list",
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
"
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2921
|
+
/* @__PURE__ */ React25.createElement("div", { className: "aura-command__list", "aria-busy": props.loading || void 0 }, props.loading ? /* @__PURE__ */ React25.createElement("div", { className: "aura-command__loading" }, /* @__PURE__ */ React25.createElement(Icon, { name: "loader-circle", className: "aura-spin" }), t.searching) : null, !flat.length ? props.loading ? null : /* @__PURE__ */ React25.createElement("div", { className: "aura-command__empty" }, props.empty != null ? props.empty : props.emptyText || t.noMatches) : /* @__PURE__ */ React25.createElement(
|
|
2922
|
+
"div",
|
|
2923
|
+
{
|
|
2924
|
+
id: listId,
|
|
2925
|
+
role: "listbox",
|
|
2926
|
+
"aria-label": props.label || t.commandMenu,
|
|
2927
|
+
"aria-busy": props.loading || void 0
|
|
2928
|
+
},
|
|
2929
|
+
groups.map(function(g, gi) {
|
|
2930
|
+
const gid = id + "-g" + gi;
|
|
2931
|
+
return /* @__PURE__ */ React25.createElement(
|
|
2932
|
+
"div",
|
|
2933
|
+
{
|
|
2934
|
+
key: g.name || gi,
|
|
2935
|
+
role: "group",
|
|
2936
|
+
"aria-labelledby": g.name ? gid : void 0,
|
|
2937
|
+
className: "aura-command__group"
|
|
2938
|
+
},
|
|
2939
|
+
g.name ? /* @__PURE__ */ React25.createElement("div", { className: "aura-command__heading", id: gid, role: "presentation" }, g.name) : null,
|
|
2940
|
+
g.items.map(function(it) {
|
|
2941
|
+
i++;
|
|
2942
|
+
const n2 = i;
|
|
2943
|
+
return /* @__PURE__ */ React25.createElement(
|
|
2944
|
+
"div",
|
|
2945
|
+
{
|
|
2946
|
+
key: it.id,
|
|
2947
|
+
id: optId(n2),
|
|
2948
|
+
role: "option",
|
|
2949
|
+
"aria-selected": n2 === active,
|
|
2950
|
+
"aria-disabled": it.disabled || void 0,
|
|
2951
|
+
className: cx(
|
|
2952
|
+
"aura-command__item",
|
|
2953
|
+
n2 === active && "is-active",
|
|
2954
|
+
it.disabled && "is-disabled"
|
|
2955
|
+
),
|
|
2956
|
+
onPointerDown: function(e) {
|
|
2957
|
+
e.preventDefault();
|
|
2958
|
+
},
|
|
2959
|
+
onPointerMove: function() {
|
|
2960
|
+
if (!it.disabled && act[0] !== it.id) act[1](it.id);
|
|
2961
|
+
},
|
|
2962
|
+
onClick: function() {
|
|
2963
|
+
run(it);
|
|
2964
|
+
}
|
|
2929
2965
|
},
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
}
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
);
|
|
2940
|
-
})),
|
|
2966
|
+
it.icon ? /* @__PURE__ */ React25.createElement(Icon, { name: it.icon }) : null,
|
|
2967
|
+
/* @__PURE__ */ React25.createElement("span", { className: "aura-command__text" }, /* @__PURE__ */ React25.createElement("span", { className: "aura-command__label" }, it.label), it.description ? /* @__PURE__ */ React25.createElement("span", { className: "aura-command__desc" }, it.description) : null),
|
|
2968
|
+
it.shortcut ? /* @__PURE__ */ React25.createElement("kbd", { className: "aura-command__kbd" }, it.shortcut) : null
|
|
2969
|
+
);
|
|
2970
|
+
})
|
|
2971
|
+
);
|
|
2972
|
+
})
|
|
2973
|
+
)),
|
|
2974
|
+
/* @__PURE__ */ React25.createElement("span", { className: "aura-sr-only", role: "status" }, props.loading ? t.searching : query && !flat.length ? t.noMatches : props.loading === false && query ? t.results(flat.length) : ""),
|
|
2941
2975
|
/* @__PURE__ */ React25.createElement("div", { className: "aura-command__foot", "aria-hidden": true }, t.commandHint, /* @__PURE__ */ React25.createElement("span", { className: "aura-command__mod" }, isMac() ? "\u2318K" : "Ctrl K"))
|
|
2942
2976
|
)
|
|
2943
2977
|
),
|
|
@@ -3127,11 +3161,20 @@ window.Aura = (() => {
|
|
|
3127
3161
|
const selectable = !!props.selectable;
|
|
3128
3162
|
const reorderable = props.reorderable !== false && !!props.columnControls;
|
|
3129
3163
|
const controls = !!props.columnControls;
|
|
3130
|
-
const
|
|
3164
|
+
const oneCallback = !!props.onStateChange;
|
|
3165
|
+
const sortState = useMaybeControlled(
|
|
3166
|
+
props.sort,
|
|
3167
|
+
props.defaultSort || null,
|
|
3168
|
+
oneCallback ? null : props.onSortChange
|
|
3169
|
+
);
|
|
3131
3170
|
const sort = sortState[0], setSort = sortState[1];
|
|
3132
3171
|
const selState = useMaybeControlled(props.selected, props.defaultSelected || [], props.onSelectionChange);
|
|
3133
3172
|
const selected = selState[0], setSelected = selState[1];
|
|
3134
|
-
const pageState = useMaybeControlled(
|
|
3173
|
+
const pageState = useMaybeControlled(
|
|
3174
|
+
props.page,
|
|
3175
|
+
props.defaultPage || 1,
|
|
3176
|
+
oneCallback ? null : props.onPageChange
|
|
3177
|
+
);
|
|
3135
3178
|
const orderState = useMaybeControlled(
|
|
3136
3179
|
props.columnOrder,
|
|
3137
3180
|
columns.map(function(c) {
|
|
@@ -3301,11 +3344,15 @@ window.Aura = (() => {
|
|
|
3301
3344
|
const pageRows = pageSize && !manual ? view.slice(first, first + pageSize) : view;
|
|
3302
3345
|
const canSortAny = !busy && (manual ? total > 1 : rows.length > 1);
|
|
3303
3346
|
const shownTotal = manual && props.totalRows == null ? first + rows.length : total;
|
|
3304
|
-
const linkPaging = !!props.getPageHref && !props.onPageChange;
|
|
3347
|
+
const linkPaging = !!props.getPageHref && !props.onPageChange && !oneCallback;
|
|
3305
3348
|
const prevLink = React28.useRef(null), nextLink = React28.useRef(null);
|
|
3306
|
-
function
|
|
3349
|
+
function emit(s, p) {
|
|
3350
|
+
if (props.onStateChange) props.onStateChange({ sort: s, page: p });
|
|
3351
|
+
}
|
|
3352
|
+
function goPage(p, focus, quiet) {
|
|
3307
3353
|
const next = Math.min(Math.max(1, p), pageCount);
|
|
3308
3354
|
if (next === page) return false;
|
|
3355
|
+
if (!quiet) emit(sort, next);
|
|
3309
3356
|
if (linkPaging) {
|
|
3310
3357
|
const a = next === page - 1 ? prevLink.current : next === page + 1 ? nextLink.current : null;
|
|
3311
3358
|
if (a) a.click();
|
|
@@ -3317,8 +3364,12 @@ window.Aura = (() => {
|
|
|
3317
3364
|
return true;
|
|
3318
3365
|
}
|
|
3319
3366
|
function sortBy(key) {
|
|
3320
|
-
|
|
3321
|
-
|
|
3367
|
+
applySort(nextSort(key));
|
|
3368
|
+
}
|
|
3369
|
+
function applySort(s) {
|
|
3370
|
+
setSort(s);
|
|
3371
|
+
if (!(manual && linkPaging)) goPage(1, void 0, true);
|
|
3372
|
+
emit(s, 1);
|
|
3322
3373
|
}
|
|
3323
3374
|
const rowHref = props.getRowHref;
|
|
3324
3375
|
function followRow(el, e) {
|
|
@@ -3533,16 +3584,14 @@ window.Aura = (() => {
|
|
|
3533
3584
|
label: t.sortAsc,
|
|
3534
3585
|
icon: "arrow-up",
|
|
3535
3586
|
onSelect: function() {
|
|
3536
|
-
|
|
3537
|
-
goPage(1);
|
|
3587
|
+
applySort({ key: c.key, dir: "asc" });
|
|
3538
3588
|
}
|
|
3539
3589
|
},
|
|
3540
3590
|
{
|
|
3541
3591
|
label: t.sortDesc,
|
|
3542
3592
|
icon: "arrow-down",
|
|
3543
3593
|
onSelect: function() {
|
|
3544
|
-
|
|
3545
|
-
goPage(1);
|
|
3594
|
+
applySort({ key: c.key, dir: "desc" });
|
|
3546
3595
|
}
|
|
3547
3596
|
},
|
|
3548
3597
|
{ separator: true }
|
|
@@ -3979,9 +4028,10 @@ window.Aura = (() => {
|
|
|
3979
4028
|
className: "aura-icon-btn",
|
|
3980
4029
|
"aria-label": label,
|
|
3981
4030
|
onClick: function(e) {
|
|
3982
|
-
if (props.onPageChange) {
|
|
4031
|
+
if (props.onPageChange || oneCallback) {
|
|
3983
4032
|
e.preventDefault();
|
|
3984
4033
|
pageState[1](p);
|
|
4034
|
+
emit(sort, p);
|
|
3985
4035
|
}
|
|
3986
4036
|
}
|
|
3987
4037
|
},
|
|
@@ -4475,7 +4525,7 @@ window.Aura = (() => {
|
|
|
4475
4525
|
var React32 = __toESM(require_react(), 1);
|
|
4476
4526
|
var Breadcrumb = React32.forwardRef(function Breadcrumb2(props, ref) {
|
|
4477
4527
|
const t = useStrings();
|
|
4478
|
-
const Link = useLinkComponent();
|
|
4528
|
+
const Link = useLinkComponent(props.linkComponent);
|
|
4479
4529
|
const items2 = props.items || [];
|
|
4480
4530
|
return /* @__PURE__ */ React32.createElement("nav", { ref, "aria-label": props.label || t.breadcrumb, className: cx("aura-crumbs", props.className) }, /* @__PURE__ */ React32.createElement("ol", null, items2.map(function(it, i) {
|
|
4481
4531
|
const last = i === items2.length - 1;
|
|
@@ -4524,7 +4574,11 @@ window.Aura = (() => {
|
|
|
4524
4574
|
|
|
4525
4575
|
// src/responsive.tsx
|
|
4526
4576
|
var React34 = __toESM(require_react(), 1);
|
|
4577
|
+
|
|
4578
|
+
// src/breakpoints.ts
|
|
4527
4579
|
var breakpoints = { sm: 640, md: 768, lg: 1024, xl: 1280 };
|
|
4580
|
+
|
|
4581
|
+
// src/responsive.tsx
|
|
4528
4582
|
var ORDER = ["base", "sm", "md", "lg", "xl"];
|
|
4529
4583
|
function useBreakpoint() {
|
|
4530
4584
|
return React34.useSyncExternalStore(subscribe, current, function() {
|
|
@@ -4693,7 +4747,7 @@ window.Aura = (() => {
|
|
|
4693
4747
|
const ch = props.change;
|
|
4694
4748
|
const dir = ch && (ch.direction || "flat");
|
|
4695
4749
|
const tone2 = ch && (ch.tone || (dir === "up" ? "positive" : dir === "down" ? "negative" : "neutral"));
|
|
4696
|
-
const Link = useLinkComponent();
|
|
4750
|
+
const Link = useLinkComponent(props.linkComponent);
|
|
4697
4751
|
const v = props.value;
|
|
4698
4752
|
const numeric = typeof v === "number" || typeof v === "string" && /\d/.test(v) && /^[\s\d.,:+\-\u2212%()\u0E3F$\u20AC\u00A3\u00A5kKmMbB]+$/.test(v.replace(/\b[A-Z]{3}\b/g, ""));
|
|
4699
4753
|
const Tag3 = props.href ? Link : props.onClick ? "button" : "div";
|
|
@@ -4717,16 +4771,21 @@ window.Aura = (() => {
|
|
|
4717
4771
|
// src/TimePicker.tsx
|
|
4718
4772
|
var React41 = __toESM(require_react(), 1);
|
|
4719
4773
|
var import_react_dom9 = __toESM(require_react_dom(), 1);
|
|
4774
|
+
|
|
4775
|
+
// src/text.ts
|
|
4776
|
+
function formatBytes(n2) {
|
|
4777
|
+
if (n2 == null) return "";
|
|
4778
|
+
if (n2 < 1024) return n2 + " B";
|
|
4779
|
+
let u = ["KB", "MB", "GB"], i = -1;
|
|
4780
|
+
do {
|
|
4781
|
+
n2 /= 1024;
|
|
4782
|
+
i++;
|
|
4783
|
+
} while (n2 >= 1024 && i < u.length - 1);
|
|
4784
|
+
return (n2 >= 10 || Math.round(n2) === n2 ? Math.round(n2) : n2.toFixed(1)) + " " + u[i];
|
|
4785
|
+
}
|
|
4720
4786
|
function pad2(n2) {
|
|
4721
4787
|
return (n2 < 10 ? "0" : "") + n2;
|
|
4722
4788
|
}
|
|
4723
|
-
function toMin(t) {
|
|
4724
|
-
const m = /^(\d{2}):(\d{2})$/.exec(t || "");
|
|
4725
|
-
return m ? +m[1] * 60 + +m[2] : null;
|
|
4726
|
-
}
|
|
4727
|
-
function fromMin(n2) {
|
|
4728
|
-
return pad2(Math.floor(n2 / 60)) + ":" + pad2(n2 % 60);
|
|
4729
|
-
}
|
|
4730
4789
|
function parseTime(text) {
|
|
4731
4790
|
let s = String(text || "").trim().toLowerCase().replace(/\s*(น\.?|นาฬิกา)$/, "").trim();
|
|
4732
4791
|
const pm = /\s*(pm|p\.m\.)$/.test(s), am = /\s*(am|a\.m\.)$/.test(s);
|
|
@@ -4739,6 +4798,18 @@ window.Aura = (() => {
|
|
|
4739
4798
|
if (hh > 23 || mm > 59) return null;
|
|
4740
4799
|
return pad2(hh) + ":" + pad2(mm);
|
|
4741
4800
|
}
|
|
4801
|
+
|
|
4802
|
+
// src/TimePicker.tsx
|
|
4803
|
+
function pad3(n2) {
|
|
4804
|
+
return (n2 < 10 ? "0" : "") + n2;
|
|
4805
|
+
}
|
|
4806
|
+
function toMin(t) {
|
|
4807
|
+
const m = /^(\d{2}):(\d{2})$/.exec(t || "");
|
|
4808
|
+
return m ? +m[1] * 60 + +m[2] : null;
|
|
4809
|
+
}
|
|
4810
|
+
function fromMin(n2) {
|
|
4811
|
+
return pad3(Math.floor(n2 / 60)) + ":" + pad3(n2 % 60);
|
|
4812
|
+
}
|
|
4742
4813
|
var TimePicker = React41.forwardRef(function TimePicker2(props, ref) {
|
|
4743
4814
|
const t = useStrings();
|
|
4744
4815
|
const auto = uid(), id = props.id || auto, listId = id + "-list";
|
|
@@ -5039,16 +5110,6 @@ window.Aura = (() => {
|
|
|
5039
5110
|
|
|
5040
5111
|
// src/FileUpload.tsx
|
|
5041
5112
|
var React42 = __toESM(require_react(), 1);
|
|
5042
|
-
function formatBytes(n2) {
|
|
5043
|
-
if (n2 == null) return "";
|
|
5044
|
-
if (n2 < 1024) return n2 + " B";
|
|
5045
|
-
let u = ["KB", "MB", "GB"], i = -1;
|
|
5046
|
-
do {
|
|
5047
|
-
n2 /= 1024;
|
|
5048
|
-
i++;
|
|
5049
|
-
} while (n2 >= 1024 && i < u.length - 1);
|
|
5050
|
-
return (n2 >= 10 || Math.round(n2) === n2 ? Math.round(n2) : n2.toFixed(1)) + " " + u[i];
|
|
5051
|
-
}
|
|
5052
5113
|
function matches(file, accept) {
|
|
5053
5114
|
if (!accept) return true;
|
|
5054
5115
|
const name = (file.name || "").toLowerCase(), type = (file.type || "").toLowerCase();
|
|
@@ -5507,6 +5568,8 @@ window.Aura = (() => {
|
|
|
5507
5568
|
|
|
5508
5569
|
// src/colorScheme.tsx
|
|
5509
5570
|
var React44 = __toESM(require_react(), 1);
|
|
5571
|
+
|
|
5572
|
+
// src/colorSchemeScript.ts
|
|
5510
5573
|
var DEFAULT_KEY = "aura-color-scheme";
|
|
5511
5574
|
var SCHEMES = ["light", "dark", "system"];
|
|
5512
5575
|
var EVENT = "aura-color-scheme";
|
|
@@ -5518,6 +5581,8 @@ window.Aura = (() => {
|
|
|
5518
5581
|
const fallback = JSON.stringify(options && options.defaultScheme || "system");
|
|
5519
5582
|
return "(function(){try{var s=localStorage.getItem(" + key + ");if(s!=='light'&&s!=='dark'&&s!=='system')s=" + fallback + `;var d=document.documentElement;d.setAttribute("data-theme",s);var dark=s==='dark'||(s==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);d.classList.toggle("dark",dark);}catch(e){}})();`;
|
|
5520
5583
|
}
|
|
5584
|
+
|
|
5585
|
+
// src/colorScheme.tsx
|
|
5521
5586
|
function ColorSchemeScript(props) {
|
|
5522
5587
|
return /* @__PURE__ */ React44.createElement(
|
|
5523
5588
|
"script",
|
|
@@ -5745,7 +5810,7 @@ window.Aura = (() => {
|
|
|
5745
5810
|
if (p >= 1 && p <= count && p !== page) st[1](p);
|
|
5746
5811
|
}
|
|
5747
5812
|
const link = props.getHref;
|
|
5748
|
-
const Link = useLinkComponent();
|
|
5813
|
+
const Link = useLinkComponent(props.linkComponent);
|
|
5749
5814
|
function item(p, label, extra) {
|
|
5750
5815
|
const common = Object.assign(
|
|
5751
5816
|
{
|
|
@@ -5780,29 +5845,40 @@ window.Aura = (() => {
|
|
|
5780
5845
|
label
|
|
5781
5846
|
);
|
|
5782
5847
|
}
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5848
|
+
function arrow(p, icon, label, rel, disabled) {
|
|
5849
|
+
if (!link || disabled)
|
|
5850
|
+
return /* @__PURE__ */ React49.createElement(
|
|
5851
|
+
IconButton,
|
|
5852
|
+
{
|
|
5853
|
+
icon,
|
|
5854
|
+
label,
|
|
5855
|
+
disabled,
|
|
5856
|
+
onClick: function() {
|
|
5857
|
+
go(p);
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
5860
|
+
);
|
|
5861
|
+
return /* @__PURE__ */ React49.createElement(
|
|
5862
|
+
Link,
|
|
5863
|
+
{
|
|
5864
|
+
href: link(p),
|
|
5865
|
+
rel,
|
|
5866
|
+
className: "aura-icon-btn",
|
|
5867
|
+
"aria-label": label,
|
|
5868
|
+
title: label,
|
|
5869
|
+
onClick: function(e) {
|
|
5870
|
+
if (props.onChange) {
|
|
5871
|
+
e.preventDefault();
|
|
5872
|
+
go(p);
|
|
5873
|
+
}
|
|
5874
|
+
}
|
|
5875
|
+
},
|
|
5876
|
+
/* @__PURE__ */ React49.createElement(Icon, { name: icon, size: "sm" })
|
|
5877
|
+
);
|
|
5878
|
+
}
|
|
5879
|
+
return /* @__PURE__ */ React49.createElement("nav", { ref, className: cx("aura-pagination", props.className), "aria-label": props.label || t.pagination }, arrow(page - 1, "chevron-left", t.prevPage, "prev", page <= 1), /* @__PURE__ */ React49.createElement("ol", { className: "aura-pagination__list" }, pageList(page, count, props.siblingCount == null ? 1 : props.siblingCount).map(function(p) {
|
|
5794
5880
|
return typeof p === "number" ? /* @__PURE__ */ React49.createElement("li", { key: p }, item(p, p)) : /* @__PURE__ */ React49.createElement("li", { key: p, className: "aura-pagination__gap", "aria-hidden": true }, "\u2026");
|
|
5795
|
-
})), /* @__PURE__ */ React49.createElement("span", { className: "aura-pagination__compact", "aria-hidden": true }, t.page(page, count)),
|
|
5796
|
-
IconButton,
|
|
5797
|
-
{
|
|
5798
|
-
icon: "chevron-right",
|
|
5799
|
-
label: t.nextPage,
|
|
5800
|
-
disabled: page >= count,
|
|
5801
|
-
onClick: function() {
|
|
5802
|
-
go(page + 1);
|
|
5803
|
-
}
|
|
5804
|
-
}
|
|
5805
|
-
));
|
|
5881
|
+
})), /* @__PURE__ */ React49.createElement("span", { className: "aura-pagination__compact", "aria-hidden": true }, t.page(page, count)), arrow(page + 1, "chevron-right", t.nextPage, "next", page >= count));
|
|
5806
5882
|
});
|
|
5807
5883
|
|
|
5808
5884
|
// src/Accordion.tsx
|
|
@@ -247,6 +247,7 @@ a.aura-btn { text-decoration: none; }
|
|
|
247
247
|
.aura-table__pager > span { margin-right: var(--aura-space-2); }
|
|
248
248
|
|
|
249
249
|
/* Icon button — 32px round, icon in the text colour */
|
|
250
|
+
a.aura-icon-btn { text-decoration: none; }
|
|
250
251
|
.aura-icon-btn {
|
|
251
252
|
width: var(--aura-control-sm); height: var(--aura-control-sm); flex: none;
|
|
252
253
|
display: inline-flex; align-items: center; justify-content: center;
|
|
@@ -692,7 +693,8 @@ a.aura-btn { text-decoration: none; }
|
|
|
692
693
|
.aura-combo__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
693
694
|
.aura-combo__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
694
695
|
.aura-combo__desc { font-size: 12px; line-height: 1.5; color: var(--aura-fg-secondary); }
|
|
695
|
-
.aura-
|
|
696
|
+
/* Same specificity as `.aura-combo__option > .aura-icon` above and later in the file, so it wins by order (4.18). */
|
|
697
|
+
.aura-combo__option > .aura-combo__check { color: var(--aura-fg-accent); }
|
|
696
698
|
.aura-combo__note { display: flex; align-items: center; gap: var(--aura-space-2); padding: var(--aura-space-3) var(--aura-space-2); font-size: 13px; color: var(--aura-fg-secondary); }
|
|
697
699
|
|
|
698
700
|
/* ---------- DatePicker / Calendar ---------- */
|
|
@@ -1147,10 +1149,23 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1147
1149
|
|
|
1148
1150
|
/* Touch screens: bigger targets for days and options. */
|
|
1149
1151
|
@media (pointer: coarse) {
|
|
1150
|
-
.aura-cal { --aura-cal-cell:
|
|
1152
|
+
.aura-cal { --aura-cal-cell: var(--aura-touch-target); }
|
|
1151
1153
|
.aura-combo__option { min-height: 44px; }
|
|
1152
|
-
.aura-segmented__option, .aura-segmented--sm .aura-segmented__option { height:
|
|
1154
|
+
.aura-segmented__option, .aura-segmented--sm .aura-segmented__option { height: var(--aura-touch-target); }
|
|
1153
1155
|
.aura-number__step { width: 44px; }
|
|
1156
|
+
/* 4.17: the rest of the controls under 44px on touch screens. */
|
|
1157
|
+
.aura-menu__item { height: var(--aura-touch-target); }
|
|
1158
|
+
.aura-page { min-width: var(--aura-touch-target); height: var(--aura-touch-target); }
|
|
1159
|
+
/* Side by side, each 44px wide (40px tall inside the 44px field), so their targets never overlap. */
|
|
1160
|
+
.aura-combo__clear, .aura-combo__toggle, .aura-date__toggle { width: var(--aura-touch-target); height: 40px; }
|
|
1161
|
+
.aura-combo__toggle, .aura-date__toggle { right: 0; }
|
|
1162
|
+
.aura-combo__clear, .aura-date .aura-combo__clear { right: var(--aura-touch-target); }
|
|
1163
|
+
.aura-combo .aura-input__control, .aura-date .aura-input__control { padding-right: calc(var(--aura-space-1) + 2 * var(--aura-touch-target)); }
|
|
1164
|
+
.aura-combo__clear::after, .aura-combo__toggle::after, .aura-date__toggle::after, .aura-tag__remove::after {
|
|
1165
|
+
content: ''; position: absolute; top: 50%; left: 50%; width: max(100%, var(--aura-touch-target)); height: max(100%, var(--aura-touch-target)); transform: translate(-50%, -50%);
|
|
1166
|
+
}
|
|
1167
|
+
.aura-tag__remove { position: relative; }
|
|
1168
|
+
.aura-combo.is-multi .aura-combo__clear, .aura-combo.is-multi .aura-combo__toggle { top: calc((var(--aura-input-height) - 2px - 40px) / 2); }
|
|
1154
1169
|
}
|
|
1155
1170
|
|
|
1156
1171
|
/* ---------- Small screens (< 640px) ---------- */
|
|
@@ -1160,7 +1175,9 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1160
1175
|
.aura-stepper--horizontal .aura-stepper__item:not(:last-child)::after { right: 8px; }
|
|
1161
1176
|
.aura-stepper--horizontal .aura-stepper__compact { display: block; }
|
|
1162
1177
|
.aura-dialog-layer:not(.aura-drawer-layer) { align-items: flex-end; padding: 0; }
|
|
1163
|
-
|
|
1178
|
+
/* The size classes set max-width; naming them here outranks them by specificity (4.18). */
|
|
1179
|
+
.aura-dialog.aura-dialog--sm, .aura-dialog.aura-dialog--md, .aura-dialog.aura-dialog--lg { max-width: none; }
|
|
1180
|
+
.aura-dialog { max-height: 92vh; max-height: 92dvh; border-radius: var(--aura-radius-2xl) var(--aura-radius-2xl) 0 0; border-bottom: 0;
|
|
1164
1181
|
padding-bottom: calc(var(--aura-space-6) + env(safe-area-inset-bottom)); animation-name: aura-sheet-in; }
|
|
1165
1182
|
.aura-dialog__foot { flex-direction: column-reverse; }
|
|
1166
1183
|
.aura-dialog__foot > * { width: 100%; }
|
|
@@ -1275,6 +1292,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1275
1292
|
flex: none; padding: 2px 6px; border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-xs);
|
|
1276
1293
|
font-family: var(--font-mono); font-size: 11px; line-height: 16px; color: var(--aura-fg-secondary); background: var(--aura-bg-canvas);
|
|
1277
1294
|
}
|
|
1295
|
+
.aura-command__loading { display: flex; align-items: center; gap: var(--aura-space-2); padding: var(--aura-space-2) var(--aura-space-3); font-size: 13px; color: var(--aura-fg-secondary); }
|
|
1278
1296
|
.aura-command__empty { margin: 0; padding: var(--aura-space-6) var(--aura-space-2); text-align: center; font-size: 14px; color: var(--aura-fg-secondary); }
|
|
1279
1297
|
.aura-command__foot { display: flex; justify-content: space-between; gap: var(--aura-space-3); padding: var(--aura-space-2) var(--aura-space-4); border-top: 1px solid var(--aura-border-default); font-size: 12px; color: var(--aura-fg-secondary); }
|
|
1280
1298
|
@media (max-width: 639.98px) {
|
package/components/index.d.ts
CHANGED
|
@@ -41,6 +41,11 @@ export interface ButtonLinkProps extends Omit<React$1.AnchorHTMLAttributes<HTMLA
|
|
|
41
41
|
/** A router's link to render instead of `<a>`, e.g. `Link` from `next/link` (client-side navigation). It gets `href`, `className`, the children and the ref. */
|
|
42
42
|
linkComponent?: React$1.ElementType | undefined;
|
|
43
43
|
}
|
|
44
|
+
/** What DataTable's onStateChange reports: the sort and the 1-based page, together. */
|
|
45
|
+
export interface DataTableState {
|
|
46
|
+
sort: DataTableSort | null;
|
|
47
|
+
page: number;
|
|
48
|
+
}
|
|
44
49
|
export interface DataTableColumn {
|
|
45
50
|
/** Key into each row object. */
|
|
46
51
|
key: string;
|
|
@@ -119,6 +124,10 @@ export interface DataTableProps {
|
|
|
119
124
|
/** Initial page when uncontrolled. Default 1. */
|
|
120
125
|
defaultPage?: number | undefined;
|
|
121
126
|
onPageChange?: ((page: number) => void) | undefined;
|
|
127
|
+
/** Sort and page in one callback (4.17): a sort click reports `{ sort, page: 1 }` once, a page change
|
|
128
|
+
* `{ sort, page }`. When set, onSortChange and onPageChange are not called for them, so an app that keeps both in
|
|
129
|
+
* the URL does one navigation per click. Pair with `sort` + `page` for controlled state. */
|
|
130
|
+
onStateChange?: ((state: DataTableState) => void) | undefined;
|
|
122
131
|
/** Adds drag/keyboard resize handles to every column that has a width. */
|
|
123
132
|
resizable?: boolean | undefined;
|
|
124
133
|
onColumnResize?: ((key: string, width: number) => void) | undefined;
|
|
@@ -362,10 +371,20 @@ export interface CommandProps {
|
|
|
362
371
|
placeholder?: string | undefined;
|
|
363
372
|
/** Default "No matches". */
|
|
364
373
|
emptyText?: string | undefined;
|
|
374
|
+
/** Shown when nothing matches, instead of `emptyText`: any content, e.g. a hint and a "Create member" button. (4.17) */
|
|
375
|
+
empty?: React$1.ReactNode | undefined;
|
|
365
376
|
/** ⌘K / Ctrl+K toggles the palette from anywhere on the page. Default true. */
|
|
366
377
|
hotkey?: boolean | undefined;
|
|
367
|
-
/** Replace the Thai-aware default filter
|
|
368
|
-
|
|
378
|
+
/** Replace the Thai-aware default filter, or `false` to show `items` as given — for results your server already
|
|
379
|
+
* searched (4.17). */
|
|
380
|
+
filter?: ((item: CommandItem, query: string) => boolean) | false | undefined;
|
|
381
|
+
/** The search text, controlled (4.17). Pair with `onQueryChange`; fetch results for it and pass them as `items`. */
|
|
382
|
+
query?: string | undefined;
|
|
383
|
+
/** Called on every keystroke, and with "" when the palette closes. (4.17) */
|
|
384
|
+
onQueryChange?: ((query: string) => void) | undefined;
|
|
385
|
+
/** Results are on their way: a "Searching…" row, `aria-busy`, and the result count announced when they arrive. The
|
|
386
|
+
* current items stay listed meanwhile. (4.17) */
|
|
387
|
+
loading?: boolean | undefined;
|
|
369
388
|
className?: string | undefined;
|
|
370
389
|
}
|
|
371
390
|
export interface TextareaProps extends FieldProps, Omit<React$1.TextareaHTMLAttributes<HTMLTextAreaElement>, "required"> {
|
|
@@ -554,6 +573,8 @@ export interface BreadcrumbProps {
|
|
|
554
573
|
onClick?: (() => void) | undefined;
|
|
555
574
|
}>;
|
|
556
575
|
label?: string | undefined;
|
|
576
|
+
/** Your router's link (e.g. `Link` from `next/link`) for this component; defaults to AuraProvider's `linkComponent`, then `<a>`. */
|
|
577
|
+
linkComponent?: React$1.ElementType | undefined;
|
|
557
578
|
className?: string | undefined;
|
|
558
579
|
}
|
|
559
580
|
export interface AvatarProps {
|
|
@@ -813,6 +834,8 @@ export interface StatChange {
|
|
|
813
834
|
label?: React$1.ReactNode | undefined;
|
|
814
835
|
}
|
|
815
836
|
export interface StatProps {
|
|
837
|
+
/** Your router's link (e.g. `Link` from `next/link`) for this component; defaults to AuraProvider's `linkComponent`, then `<a>`. */
|
|
838
|
+
linkComponent?: React$1.ElementType | undefined;
|
|
816
839
|
label: React$1.ReactNode;
|
|
817
840
|
value?: React$1.ReactNode | undefined;
|
|
818
841
|
/** Small unit after the value ("งาน", "คน", "%"). */
|
|
@@ -943,9 +966,12 @@ export interface PaginationProps {
|
|
|
943
966
|
onChange?: ((page: number) => void) | undefined;
|
|
944
967
|
/** Pages shown each side of the current one. Default 1. */
|
|
945
968
|
siblingCount?: number | undefined;
|
|
946
|
-
/** Render real links
|
|
969
|
+
/** Render real links — page numbers and the previous / next arrows (4.17) — through your router's link. With
|
|
970
|
+
* `onChange` too, onChange runs instead of following the link. */
|
|
947
971
|
getHref?: ((page: number) => string) | undefined;
|
|
948
972
|
label?: string | undefined;
|
|
973
|
+
/** Your router's link (e.g. `Link` from `next/link`) for this component; defaults to AuraProvider's `linkComponent`, then `<a>`. */
|
|
974
|
+
linkComponent?: React$1.ElementType | undefined;
|
|
949
975
|
className?: string | undefined;
|
|
950
976
|
}
|
|
951
977
|
export interface AccordionItem {
|
|
@@ -1077,11 +1103,11 @@ export type FormatDateOptions = DateDisplayOptions & {
|
|
|
1077
1103
|
};
|
|
1078
1104
|
/** Format an ISO date for display, e.g. "18 ก.ย. 2569" (th, Buddhist) or "18 Sept 2026" (en, Gregorian). */
|
|
1079
1105
|
export declare function formatDate(iso: ISODate | null | undefined, opts?: FormatDateOptions): string;
|
|
1106
|
+
/** Parse typed text: dd/mm/yyyy (Buddhist years ≥ 2400 are converted), d-m-yyyy, d.m.yyyy, yyyy-mm-dd or '18 ก.ย. 2569' / '18 Sep 2026'. */
|
|
1107
|
+
export declare function parseDate(text: string | null | undefined): ISODate | null;
|
|
1080
1108
|
/** formatDate bound to the nearest AuraProvider: its locale and calendar (English, Gregorian without one).
|
|
1081
1109
|
* Options you pass still win. Use it in components; plain formatDate() stays for code outside React. */
|
|
1082
1110
|
export declare function useFormatDate(): (iso: ISODate | null | undefined, opts?: FormatDateOptions) => string;
|
|
1083
|
-
/** Parse typed text: dd/mm/yyyy (Buddhist years ≥ 2400 are converted), d-m-yyyy, d.m.yyyy, yyyy-mm-dd or '18 ก.ย. 2569' / '18 Sep 2026'. */
|
|
1084
|
-
export declare function parseDate(text: string | null | undefined): ISODate | null;
|
|
1085
1111
|
export declare const Calendar: React$1.ForwardRefExoticComponent<CalendarProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1086
1112
|
/** Typed date field + calendar popover. English / Gregorian unless a locale is set; `th` shows Buddhist-era dates (18 ก.ย. 2569) and accepts พ.ศ. or ค.ศ. years. The value is always a Gregorian ISO date. */
|
|
1087
1113
|
export declare const DatePicker: React$1.ForwardRefExoticComponent<DatePickerProps & React$1.RefAttributes<HTMLInputElement>>;
|
|
@@ -1249,11 +1275,11 @@ export declare function useAuraLocale(): AuraLocaleValue;
|
|
|
1249
1275
|
/** The provider's density, for portals that render outside its wrapper. */
|
|
1250
1276
|
export declare function useDensity(): "comfortable" | "compact" | undefined;
|
|
1251
1277
|
export declare const Stat: React$1.ForwardRefExoticComponent<StatProps & React$1.RefAttributes<HTMLElement>>;
|
|
1278
|
+
/** 1536 → "1.5 KB". */
|
|
1279
|
+
export declare function formatBytes(n: number | null | undefined): string;
|
|
1252
1280
|
/** Parse typed time: 9 · 09 · 930 · 0930 · 9:30 · 9.30 · 09.30 น. · 9:30 pm → "HH:mm" (24-hour) or null. */
|
|
1253
1281
|
export declare function parseTime(text: string | null | undefined): string | null;
|
|
1254
1282
|
export declare const TimePicker: React$1.ForwardRefExoticComponent<TimePickerProps & React$1.RefAttributes<HTMLInputElement>>;
|
|
1255
|
-
/** 1536 → "1.5 KB". */
|
|
1256
|
-
export declare function formatBytes(n: number | null | undefined): string;
|
|
1257
1283
|
export declare const FileUpload: React$1.ForwardRefExoticComponent<FileUploadProps & React$1.RefAttributes<HTMLInputElement>>;
|
|
1258
1284
|
/** WCAG contrast ratio of two #hex colours. */
|
|
1259
1285
|
export declare function contrast(a: string, b: string): number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-tokens",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.18.0",
|
|
4
4
|
"description": "AURA Design System — tokens (CSS variables, Tailwind preset, Figma variables), theme contrast checks and token lint.",
|
|
5
5
|
"main": "tailwind.tokens.cjs",
|
|
6
6
|
"types": "components/index.d.ts",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"tailwind.config.ts",
|
|
14
14
|
"tailwind.tokens.cjs",
|
|
15
15
|
"aura-tailwind.css",
|
|
16
|
+
"aura-tailwind.prefixed.css",
|
|
16
17
|
"figma-variables.csv",
|
|
17
18
|
"eslint-plugin-aura.js",
|
|
18
19
|
"components/aura.bundle.js",
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
"./tokens.json": "./tokens.json",
|
|
33
34
|
"./tailwind": "./tailwind.tokens.cjs",
|
|
34
35
|
"./tailwind.css": "./aura-tailwind.css",
|
|
36
|
+
"./tailwind.prefixed.css": "./aura-tailwind.prefixed.css",
|
|
35
37
|
"./components.js": "./components/aura.bundle.js",
|
|
36
38
|
"./components.css": "./components/aura.components.css",
|
|
37
39
|
"./eslint-plugin": "./eslint-plugin-aura.js"
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
"a11y": "node scripts/a11y-check.js",
|
|
42
44
|
"check:tailwind4": "node scripts/tailwind4-check.mjs",
|
|
43
45
|
"lint:tokens": "node scripts/lint-tokens.js ../react/src && node scripts/lint-tokens.js ../react/styles",
|
|
44
|
-
"check:generated": "node scripts/build-tokens.js && git diff --exit-code -- aura.css aura-fonts.css aura-fonts.local.css tailwind.tokens.cjs aura-tailwind.css figma-variables.csv",
|
|
46
|
+
"check:generated": "node scripts/build-tokens.js && git diff --exit-code -- aura.css aura-fonts.css aura-fonts.local.css tailwind.tokens.cjs aura-tailwind.css aura-tailwind.prefixed.css figma-variables.csv",
|
|
45
47
|
"prepack": "npm run build",
|
|
46
48
|
"check:fonts": "node scripts/fonts-check.mjs"
|
|
47
49
|
},
|
package/tokens.json
CHANGED