@a.nemreen/dga-ui 0.3.16 → 0.3.17
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 +140 -127
- package/LICENSE +21 -21
- package/README.md +474 -474
- package/fesm2022/a.nemreen-dga-ui.mjs +122 -106
- package/package.json +1 -1
- package/types/a.nemreen-dga-ui.d.ts +24 -12
package/README.md
CHANGED
|
@@ -1,474 +1,474 @@
|
|
|
1
|
-
# `@a.nemreen/dga-ui`
|
|
2
|
-
|
|
3
|
-
<p align="center">
|
|
4
|
-
<img src="https://cdn.jsdelivr.net/npm/@a.nemreen/dga-ui@0.2.1/cover.jpg" alt="DGA Angular — design tokens & UI" width="100%" />
|
|
5
|
-
</p>
|
|
6
|
-
|
|
7
|
-
[](https://www.npmjs.com/package/@a.nemreen/dga-ui)
|
|
8
|
-
[](https://github.com/nemreen/dga-angular/blob/main/LICENSE)
|
|
9
|
-
[](https://angular.dev)
|
|
10
|
-
[](https://tailwindcss.com)
|
|
11
|
-
[](https://nemreen.info/dga/)
|
|
12
|
-
|
|
13
|
-
Standalone Angular UI components for the DGA design system — forms, overlays, navigation, portal shell, and layout. Styled with Tailwind utilities mapped to [`@a.nemreen/dga-tokens`](https://www.npmjs.com/package/@a.nemreen/dga-tokens).
|
|
14
|
-
|
|
15
|
-
**Live demo:** [nemreen.info/dga](https://nemreen.info/dga/)
|
|
16
|
-
|
|
17
|
-
> Version **0.3.x** until public API freeze (1.0).
|
|
18
|
-
|
|
19
|
-
## Changelog
|
|
20
|
-
|
|
21
|
-
[CHANGELOG.md](https://github.com/nemreen/dga-angular/blob/main/CHANGELOG.md) ships with this package. The same notes, in Arabic and English, are at [nemreen.info/dga/docs/changelog](https://nemreen.info/dga/docs/changelog).
|
|
22
|
-
|
|
23
|
-
## Features
|
|
24
|
-
|
|
25
|
-
- Standalone Angular 19+ components (no NgModules)
|
|
26
|
-
- RTL-first / Arabic-ready (logical CSS + locale-aware chrome)
|
|
27
|
-
- Forms: input, select, autocomplete (async/creatable), checkbox, radio, switch, OTP, upload, date/time picker, signature pad, rich text, …
|
|
28
|
-
- Overlays: dialog, modal, drawer, bottom sheet, popover, toast, menu, tooltip, command
|
|
29
|
-
- Shell: header, top bar, hero, footer, preloader, theme toggle, locale toggle
|
|
30
|
-
- Feedback & a11y: alert, cookies, skip link, notification inbox (accessibility panel → `@a.nemreen/a11y`)
|
|
31
|
-
- Data: table (templates, filters, expand, bulk), virtual list, export, carousel, chart
|
|
32
|
-
- Content: timeline, calendar events, FAQ, QR/barcode, metrics
|
|
33
|
-
- Layout: card, section, grid, clamp, expandable, app shell
|
|
34
|
-
|
|
35
|
-
## Install
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
npm install @a.nemreen/dga-ui @a.nemreen/dga-tokens
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
**Peers:** `@angular/core` / `@angular/common` / `@angular/forms` / `@angular/platform-browser` ^19–22, `@a.nemreen/dga-tokens` ^0.2 || ^0.3.
|
|
42
|
-
|
|
43
|
-
## Library layout
|
|
44
|
-
|
|
45
|
-
Sources live under `src/lib/<domain>/<component>/`. Place new work in the matching domain — do not add new top-level peers under `lib/`.
|
|
46
|
-
|
|
47
|
-
| Domain | Use for |
|
|
48
|
-
|--------|---------|
|
|
49
|
-
| `primitives/` | Visual atoms (button, icon, badge, …) |
|
|
50
|
-
| `forms/` | Inputs, selects, field chrome |
|
|
51
|
-
| `overlays/` | Floating UI (dialog, toast, menu, …) |
|
|
52
|
-
| `feedback/` | Status and user-response UI (alert, cookies, a11y, …) |
|
|
53
|
-
| `navigation/` | Wayfinding (tabs, breadcrumb, side-nav, …) |
|
|
54
|
-
| `layout/` | Structure wrappers (card, section, grid, …) |
|
|
55
|
-
| `shell/` | Page chrome (header, footer, hero, …) |
|
|
56
|
-
| `content/` | Content presentation (list, quote, metric, …) |
|
|
57
|
-
| `data/` | Tables, charts, export |
|
|
58
|
-
| `domain/` | Locale/region data helpers (not UI). Saudi cities ship as `@a.nemreen/dga-ui/saudi-cities`. |
|
|
59
|
-
| `utils/` | Internal helpers only (not exported) |
|
|
60
|
-
|
|
61
|
-
Import from the public package surface — do not deep-import `src/lib/...` paths.
|
|
62
|
-
|
|
63
|
-
New `dga-*` custom elements must also be listed in `@a.nemreen/dga-tokens` `styles/host-compat.css` (`:is(...)`) so host-app `*` / `a` resets cannot flatten them.
|
|
64
|
-
|
|
65
|
-
### Secondary entry points
|
|
66
|
-
|
|
67
|
-
Heavier shell pieces ship as separate FESMs so the primary bundle stays lean:
|
|
68
|
-
|
|
69
|
-
```ts
|
|
70
|
-
import { DgaHeader } from '@a.nemreen/dga-ui/header';
|
|
71
|
-
import { DgaCookies } from '@a.nemreen/dga-ui/cookies';
|
|
72
|
-
import { DgaDatePicker } from '@a.nemreen/dga-ui/date-picker';
|
|
73
|
-
import { DgaChart } from '@a.nemreen/dga-ui/chart';
|
|
74
|
-
import { DgaChatbot } from '@a.nemreen/dga-ui/chatbot';
|
|
75
|
-
import { DgaPageTransition } from '@a.nemreen/dga-ui/page-transition';
|
|
76
|
-
import { DGA_SAUDI_CITIES } from '@a.nemreen/dga-ui/saudi-cities';
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Accessibility tools live in a separate package — [`@a.nemreen/a11y`](https://www.npmjs.com/package/@a.nemreen/a11y) — mount with `Accessibility.mount()`.
|
|
80
|
-
|
|
81
|
-
## Setup
|
|
82
|
-
|
|
83
|
-
```css
|
|
84
|
-
@import 'tailwindcss';
|
|
85
|
-
@import '@a.nemreen/dga-tokens/styles.css';
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Keep existing app resets (`* { margin: 0; padding: 0 }`, `a { color: var(--color-mainColor) }`). Tokens ship unlayered `host-compat.css` (last in `styles.css`) so DGA components win those globals. New `dga-*` tags must be added to that `:is()` list. Optional: wrap leftover host CSS in `@layer base` so *your* Tailwind utilities also win — see the tokens README.
|
|
89
|
-
|
|
90
|
-
Load Arabic Google Fonts (IBM Plex default; see `@a.nemreen/dga-tokens` README / `DgaFontService`).
|
|
91
|
-
|
|
92
|
-
Scan library sources so Tailwind keeps component utilities (path may vary):
|
|
93
|
-
|
|
94
|
-
```css
|
|
95
|
-
@source "../node_modules/@a.nemreen/dga-ui/**/*.{mjs,js}";
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
```ts
|
|
99
|
-
import {
|
|
100
|
-
DgaButton,
|
|
101
|
-
DgaInput,
|
|
102
|
-
DgaLabel,
|
|
103
|
-
DgaBadge,
|
|
104
|
-
DgaAlert,
|
|
105
|
-
DgaCheckbox,
|
|
106
|
-
DgaRadio,
|
|
107
|
-
DgaSelect,
|
|
108
|
-
DgaNativeSelect,
|
|
109
|
-
DgaField,
|
|
110
|
-
DgaSpinner,
|
|
111
|
-
DgaDialog,
|
|
112
|
-
DgaToast,
|
|
113
|
-
DgaCard,
|
|
114
|
-
DgaDivider,
|
|
115
|
-
DgaIcon,
|
|
116
|
-
DgaTable,
|
|
117
|
-
DgaBottomSheet,
|
|
118
|
-
DgaPopover,
|
|
119
|
-
DgaThemeToggle,
|
|
120
|
-
DgaLocaleToggle,
|
|
121
|
-
} from '@a.nemreen/dga-ui';
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Components
|
|
125
|
-
|
|
126
|
-
### Icon
|
|
127
|
-
|
|
128
|
-
Two layers, both HugeIcons Stroke Rounded (DGA / Platforms Code family):
|
|
129
|
-
|
|
130
|
-
1. **Chrome** — curated inline SVG via `name` (paints with the first frame; use in buttons, fields, menus).
|
|
131
|
-
2. **Content** — optional font via `glyph` (opt into `@a.nemreen/dga-tokens/styles/icon-font.css`).
|
|
132
|
-
|
|
133
|
-
```html
|
|
134
|
-
<!-- Chrome (always available) -->
|
|
135
|
-
<dga-icon name="search" size="sm" />
|
|
136
|
-
<dga-icon name="arrowNext" size="sm" label="التالي" />
|
|
137
|
-
<dga-icon name="riyal" size="md" />
|
|
138
|
-
|
|
139
|
-
<!-- Content (requires icon-font.css) -->
|
|
140
|
-
<dga-icon glyph="search-01" size="xl" />
|
|
141
|
-
<dga-icon glyph="notification-02" size="xl" tone="primary" />
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
Use `arrowNext` / `arrowPrev` for forward/back — they mirror under `dir="rtl"`. Prefer literal `arrowLeft` / `arrowRight` only when you mean that physical direction.
|
|
145
|
-
|
|
146
|
-
Sizes (px): `2xs` 10 · `xs` 14 · `sm` 16 · `md` 18 · `lg` 20 · `xl` 24 · `2xl` 28 · `3xl` 32.
|
|
147
|
-
|
|
148
|
-
`DgaIcon` inlines a small HugeIcons core map (close / menu / search / chevrons / check / user / …) and lazy-loads the curated catalog on the first non-core `name`. Apps can add icons without forking the library:
|
|
149
|
-
|
|
150
|
-
```ts
|
|
151
|
-
import { provideDgaIcons } from '@a.nemreen/dga-ui';
|
|
152
|
-
|
|
153
|
-
bootstrapApplication(App, {
|
|
154
|
-
providers: [
|
|
155
|
-
provideDgaIcons({
|
|
156
|
-
myBrand: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">…</svg>`,
|
|
157
|
-
}),
|
|
158
|
-
],
|
|
159
|
-
});
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
```html
|
|
163
|
-
<dga-icon name="myBrand" size="md" />
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
Source: `@hugeicons/core-free-icons` (same family as design.dga.gov.sa). Regenerate with `node scripts/generate-dga-icons.mjs`.
|
|
167
|
-
|
|
168
|
-
### Scroll to top
|
|
169
|
-
|
|
170
|
-
Floating control that appears after the page scrolls past a threshold. Mount once at the app root; it stacks above `@a.nemreen/a11y` by default.
|
|
171
|
-
|
|
172
|
-
```html
|
|
173
|
-
<dga-scroll-top position="end" [threshold]="320" />
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### Button
|
|
177
|
-
|
|
178
|
-
```html
|
|
179
|
-
<button dgaButton type="button">حفظ</button>
|
|
180
|
-
<button dgaButton variant="outline" size="sm">إلغاء</button>
|
|
181
|
-
<button dgaButton variant="danger" disabled>حذف</button>
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Input + Label + Field
|
|
185
|
-
|
|
186
|
-
```html
|
|
187
|
-
<label dgaLabel dgaRequired for="email">البريد</label>
|
|
188
|
-
<input dgaInput id="email" type="email" />
|
|
189
|
-
<textarea dgaInput rows="3"></textarea>
|
|
190
|
-
|
|
191
|
-
<dga-field label="البريد" controlId="email" required hint="لن نشارك بريدك.">
|
|
192
|
-
<input dgaInput id="email" type="email" />
|
|
193
|
-
</dga-field>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Select
|
|
197
|
-
|
|
198
|
-
Configurable select (search, multi, always-open):
|
|
199
|
-
|
|
200
|
-
```html
|
|
201
|
-
<dga-select [options]="cities" [(value)]="city" />
|
|
202
|
-
<dga-select searchable [options]="cities" [(value)]="city" />
|
|
203
|
-
<dga-select multiple [options]="cities" [(value)]="cities" />
|
|
204
|
-
<dga-select multiple searchable [options]="cities" [(value)]="cities" />
|
|
205
|
-
<dga-select openMode="always" [options]="cities" [(value)]="city" />
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
Native `<select>` styling for simple forms:
|
|
209
|
-
|
|
210
|
-
```html
|
|
211
|
-
<select dgaSelect>
|
|
212
|
-
<option value="riyadh">الرياض</option>
|
|
213
|
-
</select>
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Checkbox + Radio
|
|
217
|
-
|
|
218
|
-
```html
|
|
219
|
-
<label>
|
|
220
|
-
<input dgaCheckbox type="checkbox" />
|
|
221
|
-
أوافق
|
|
222
|
-
</label>
|
|
223
|
-
|
|
224
|
-
<label>
|
|
225
|
-
<input dgaRadio type="radio" name="plan" value="basic" />
|
|
226
|
-
أساسية
|
|
227
|
-
</label>
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### Badge
|
|
231
|
-
|
|
232
|
-
```html
|
|
233
|
-
<dga-badge variant="success">مكتمل</dga-badge>
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### Alert
|
|
237
|
-
|
|
238
|
-
```html
|
|
239
|
-
<dga-alert variant="warning" title="تنبيه">تحقق من البيانات.</dga-alert>
|
|
240
|
-
<dga-alert dismissible (dismissed)="onDismiss()">يمكن إغلاقه</dga-alert>
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### Spinner
|
|
244
|
-
|
|
245
|
-
```html
|
|
246
|
-
<dga-spinner />
|
|
247
|
-
<dga-spinner size="lg" tone="neutral" />
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Preloader (optional first-load)
|
|
251
|
-
|
|
252
|
-
Full-screen brand overlay; auto-hides when the document is ready and `minDuration` elapses. Omit the tag if you do not want it.
|
|
253
|
-
|
|
254
|
-
```html
|
|
255
|
-
<dga-preloader
|
|
256
|
-
brand="بوابة الخدمات"
|
|
257
|
-
label="جاري التحميل"
|
|
258
|
-
[minDuration]="1000"
|
|
259
|
-
[once]="true"
|
|
260
|
-
persist="local"
|
|
261
|
-
/>
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
- `once` + `persist="local"` - show only on the visitor’s first visit
|
|
265
|
-
- `persist="session"` - once per tab session
|
|
266
|
-
- `persist="none"` or `[once]="false"` - every load
|
|
267
|
-
- Optional `logoSrc` replaces the default geometric mark
|
|
268
|
-
- `(closed)` fires after the exit animation
|
|
269
|
-
|
|
270
|
-
```ts
|
|
271
|
-
import { DgaPreloader } from '@a.nemreen/dga-ui';
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### Dialog
|
|
275
|
-
|
|
276
|
-
```html
|
|
277
|
-
<dga-dialog [(open)]="open" title="تأكيد">
|
|
278
|
-
<p>هل أنت متأكد؟</p>
|
|
279
|
-
<div dgaDialogActions>
|
|
280
|
-
<button dgaButton variant="ghost" (click)="open = false">إلغاء</button>
|
|
281
|
-
<button dgaButton (click)="confirm()">تأكيد</button>
|
|
282
|
-
</div>
|
|
283
|
-
</dga-dialog>
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### Modal
|
|
287
|
-
|
|
288
|
-
```html
|
|
289
|
-
<dga-modal
|
|
290
|
-
[(open)]="open"
|
|
291
|
-
title="تفاصيل الطلب"
|
|
292
|
-
description="راجع البيانات قبل المتابعة"
|
|
293
|
-
size="lg"
|
|
294
|
-
animation="scale"
|
|
295
|
-
>
|
|
296
|
-
<p>محتوى النافذة المنبثقة.</p>
|
|
297
|
-
<div dgaModalActions>
|
|
298
|
-
<button dgaButton variant="ghost" (click)="open = false">إلغاء</button>
|
|
299
|
-
<button dgaButton (click)="confirm()">تأكيد</button>
|
|
300
|
-
</div>
|
|
301
|
-
</dga-modal>
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
### Toast
|
|
305
|
-
|
|
306
|
-
```html
|
|
307
|
-
<dga-toast [(open)]="show" variant="success" title="تم">حُفظ السجل.</dga-toast>
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
### Tooltip / Switch / Progress / Nav (Wave I)
|
|
311
|
-
|
|
312
|
-
```html
|
|
313
|
-
<dga-switch [(checked)]="on" label="الإشعارات" />
|
|
314
|
-
<a dgaLink href="#">رابط</a>
|
|
315
|
-
<dga-progress [value]="60" />
|
|
316
|
-
<dga-skeleton />
|
|
317
|
-
<dga-skeleton [lines]="3" animation="shimmer" />
|
|
318
|
-
<dga-skeleton shape="circle" size="lg" />
|
|
319
|
-
<dga-tooltip title="مساعدة" text="وصف مختصر">
|
|
320
|
-
<button dgaButton size="sm">؟</button>
|
|
321
|
-
</dga-tooltip>
|
|
322
|
-
|
|
323
|
-
<dga-breadcrumb [items]="[{ label: 'الرئيسية', href: '#' }, { label: 'الحالي' }]" />
|
|
324
|
-
<dga-tabs [(selected)]="tab">
|
|
325
|
-
<dga-tab value="a" label="أ">...</dga-tab>
|
|
326
|
-
</dga-tabs>
|
|
327
|
-
<dga-content-switcher [(selected)]="view">
|
|
328
|
-
<dga-content-switcher-panel value="all" label="الكل">...</dga-content-switcher-panel>
|
|
329
|
-
</dga-content-switcher>
|
|
330
|
-
<dga-accordion>
|
|
331
|
-
<dga-accordion-item title="سؤال">جواب</dga-accordion-item>
|
|
332
|
-
</dga-accordion>
|
|
333
|
-
<dga-pagination [(page)]="page" [totalPages]="10" />
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
## Layout recipes
|
|
337
|
-
|
|
338
|
-
Prefer DGA spacing tokens (`gap-md`, `p-xl`, `py-3xl`) over raw pixel values. For page width, use `max-w-(--container-*)` - plain `max-w-5xl` binds to the spacing scale in Tailwind v4.
|
|
339
|
-
|
|
340
|
-
### Stack (column)
|
|
341
|
-
|
|
342
|
-
```html
|
|
343
|
-
<div class="flex flex-col gap-md">
|
|
344
|
-
<p>صف واحد</p>
|
|
345
|
-
<p>صف آخر</p>
|
|
346
|
-
</div>
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
### Inline row
|
|
350
|
-
|
|
351
|
-
```html
|
|
352
|
-
<div class="flex flex-wrap items-center gap-md">
|
|
353
|
-
<button dgaButton>حفظ</button>
|
|
354
|
-
<button dgaButton variant="ghost">إلغاء</button>
|
|
355
|
-
</div>
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
### Split (space between)
|
|
359
|
-
|
|
360
|
-
```html
|
|
361
|
-
<div class="flex items-center justify-between gap-xl">
|
|
362
|
-
<h2 class="text-display-sm">العنوان</h2>
|
|
363
|
-
<div class="flex gap-sm">…</div>
|
|
364
|
-
</div>
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### Responsive grid
|
|
368
|
-
|
|
369
|
-
```html
|
|
370
|
-
<div class="grid grid-cols-1 gap-lg md:grid-cols-2 lg:grid-cols-3">
|
|
371
|
-
<dga-card title="أ">…</dga-card>
|
|
372
|
-
<dga-card title="ب">…</dga-card>
|
|
373
|
-
<dga-card title="ج">…</dga-card>
|
|
374
|
-
</div>
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
Or use the thin wrapper:
|
|
378
|
-
|
|
379
|
-
```html
|
|
380
|
-
<dga-grid [cols]="3" gap="lg">
|
|
381
|
-
<dga-card title="أ">…</dga-card>
|
|
382
|
-
<dga-card title="ب">…</dga-card>
|
|
383
|
-
<dga-card title="ج">…</dga-card>
|
|
384
|
-
</dga-grid>
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
### Contained section
|
|
388
|
-
|
|
389
|
-
```html
|
|
390
|
-
<dga-section title="القسم" subtitle="وصف قصير" contained>
|
|
391
|
-
محتوى القسم
|
|
392
|
-
</dga-section>
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
### Portal home shell (consumable across apps)
|
|
396
|
-
|
|
397
|
-
Compose the official home template with library primitives only - no page-local CSS required:
|
|
398
|
-
|
|
399
|
-
```html
|
|
400
|
-
<dga-top-bar registrationId="00000000000" />
|
|
401
|
-
|
|
402
|
-
<dga-header
|
|
403
|
-
appearance="portal"
|
|
404
|
-
mobileNav="sheet"
|
|
405
|
-
brand="شعار المنصة"
|
|
406
|
-
brandSlogan="بوابة الجهة"
|
|
407
|
-
brandHref="/"
|
|
408
|
-
[items]="navItems"
|
|
409
|
-
[actions]="headerActions"
|
|
410
|
-
(actionClick)="onAction($event)"
|
|
411
|
-
/>
|
|
412
|
-
<!-- mobileNav: sheet | fullscreen | push -->
|
|
413
|
-
|
|
414
|
-
<dga-hero appearance="portal" [slides]="heroSlides" [(activeIndex)]="i" />
|
|
415
|
-
|
|
416
|
-
<dga-section
|
|
417
|
-
width="wide"
|
|
418
|
-
tone="surface"
|
|
419
|
-
title="قسم من نحن"
|
|
420
|
-
subtitle="…"
|
|
421
|
-
>
|
|
422
|
-
<button dgaSectionActions dgaButton variant="outline">إجراء ثانوي</button>
|
|
423
|
-
<dga-grid [cols]="4" gap="xl">
|
|
424
|
-
<dga-metric appearance="stat" value="1.5M" label="شخص">
|
|
425
|
-
<dga-icon-badge dgaMetricIcon>
|
|
426
|
-
<dga-icon name="user" tone="primary" />
|
|
427
|
-
</dga-icon-badge>
|
|
428
|
-
</dga-metric>
|
|
429
|
-
</dga-grid>
|
|
430
|
-
</dga-section>
|
|
431
|
-
|
|
432
|
-
<dga-card title="عنوان البطاقة" description="نص إضافي">
|
|
433
|
-
<dga-icon-badge dgaCardLead>
|
|
434
|
-
<dga-icon name="home" tone="primary" />
|
|
435
|
-
</dga-icon-badge>
|
|
436
|
-
<div dgaCardActions>
|
|
437
|
-
<button dgaButton variant="outline" size="sm">اجراء ثانوي</button>
|
|
438
|
-
<button dgaButton size="sm">اجراء</button>
|
|
439
|
-
</div>
|
|
440
|
-
</dga-card>
|
|
441
|
-
|
|
442
|
-
<dga-card>
|
|
443
|
-
<dga-card-media dgaCardMedia alt="خبر" />
|
|
444
|
-
…
|
|
445
|
-
</dga-card>
|
|
446
|
-
|
|
447
|
-
<dga-logo-tile label="شريك" />
|
|
448
|
-
<dga-footer
|
|
449
|
-
appearance="brand"
|
|
450
|
-
[columns]="footerColumns"
|
|
451
|
-
[iconGroups]="footerIconGroups"
|
|
452
|
-
[bottomLinks]="footerBottomLinks"
|
|
453
|
-
[logos]="footerLogos"
|
|
454
|
-
copyright="جميع الحقوق محفوظة © 2026"
|
|
455
|
-
meta="آخر تحديث للموقع في 11 سبتمبر 2026 7:30 ص"
|
|
456
|
-
/>
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
Portal tokens (layout sizes): `--size-hero-portal` (491px), `--size-header-portal` (72px), `--size-icon-badge` (40px), `--size-dot` (16px).
|
|
460
|
-
|
|
461
|
-
### Content + sticky aside
|
|
462
|
-
|
|
463
|
-
```html
|
|
464
|
-
<div class="mx-auto grid max-w-(--container-7xl) gap-3xl px-xl md:grid-cols-[1fr_auto]">
|
|
465
|
-
<main class="min-w-0">…</main>
|
|
466
|
-
<dga-side-info title="في هذه الصفحة" [items]="tocItems" />
|
|
467
|
-
</div>
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
## License
|
|
471
|
-
|
|
472
|
-
MIT — see [LICENSE](./LICENSE). Copyright (c) 2026 Ahmed Nemreen.
|
|
473
|
-
|
|
474
|
-
Use it in any project. **Do not rebrand and sell it as your own unique product.**
|
|
1
|
+
# `@a.nemreen/dga-ui`
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://cdn.jsdelivr.net/npm/@a.nemreen/dga-ui@0.2.1/cover.jpg" alt="DGA Angular — design tokens & UI" width="100%" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@a.nemreen/dga-ui)
|
|
8
|
+
[](https://github.com/nemreen/dga-angular/blob/main/LICENSE)
|
|
9
|
+
[](https://angular.dev)
|
|
10
|
+
[](https://tailwindcss.com)
|
|
11
|
+
[](https://nemreen.info/dga/)
|
|
12
|
+
|
|
13
|
+
Standalone Angular UI components for the DGA design system — forms, overlays, navigation, portal shell, and layout. Styled with Tailwind utilities mapped to [`@a.nemreen/dga-tokens`](https://www.npmjs.com/package/@a.nemreen/dga-tokens).
|
|
14
|
+
|
|
15
|
+
**Live demo:** [nemreen.info/dga](https://nemreen.info/dga/)
|
|
16
|
+
|
|
17
|
+
> Version **0.3.x** until public API freeze (1.0).
|
|
18
|
+
|
|
19
|
+
## Changelog
|
|
20
|
+
|
|
21
|
+
[CHANGELOG.md](https://github.com/nemreen/dga-angular/blob/main/CHANGELOG.md) ships with this package. The same notes, in Arabic and English, are at [nemreen.info/dga/docs/changelog](https://nemreen.info/dga/docs/changelog).
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- Standalone Angular 19+ components (no NgModules)
|
|
26
|
+
- RTL-first / Arabic-ready (logical CSS + locale-aware chrome)
|
|
27
|
+
- Forms: input, select, autocomplete (async/creatable), checkbox, radio, switch, OTP, upload, date/time picker, signature pad, rich text, …
|
|
28
|
+
- Overlays: dialog, modal, drawer, bottom sheet, popover, toast, menu, tooltip, command
|
|
29
|
+
- Shell: header, top bar, hero, footer, preloader, theme toggle, locale toggle
|
|
30
|
+
- Feedback & a11y: alert, cookies, skip link, notification inbox (accessibility panel → `@a.nemreen/a11y`)
|
|
31
|
+
- Data: table (templates, filters, expand, bulk), virtual list, export, carousel, chart
|
|
32
|
+
- Content: timeline, calendar events, FAQ, QR/barcode, metrics
|
|
33
|
+
- Layout: card, section, grid, clamp, expandable, app shell
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install @a.nemreen/dga-ui @a.nemreen/dga-tokens
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Peers:** `@angular/core` / `@angular/common` / `@angular/forms` / `@angular/platform-browser` ^19–22, `@a.nemreen/dga-tokens` ^0.2 || ^0.3.
|
|
42
|
+
|
|
43
|
+
## Library layout
|
|
44
|
+
|
|
45
|
+
Sources live under `src/lib/<domain>/<component>/`. Place new work in the matching domain — do not add new top-level peers under `lib/`.
|
|
46
|
+
|
|
47
|
+
| Domain | Use for |
|
|
48
|
+
|--------|---------|
|
|
49
|
+
| `primitives/` | Visual atoms (button, icon, badge, …) |
|
|
50
|
+
| `forms/` | Inputs, selects, field chrome |
|
|
51
|
+
| `overlays/` | Floating UI (dialog, toast, menu, …) |
|
|
52
|
+
| `feedback/` | Status and user-response UI (alert, cookies, a11y, …) |
|
|
53
|
+
| `navigation/` | Wayfinding (tabs, breadcrumb, side-nav, …) |
|
|
54
|
+
| `layout/` | Structure wrappers (card, section, grid, …) |
|
|
55
|
+
| `shell/` | Page chrome (header, footer, hero, …) |
|
|
56
|
+
| `content/` | Content presentation (list, quote, metric, …) |
|
|
57
|
+
| `data/` | Tables, charts, export |
|
|
58
|
+
| `domain/` | Locale/region data helpers (not UI). Saudi cities ship as `@a.nemreen/dga-ui/saudi-cities`. |
|
|
59
|
+
| `utils/` | Internal helpers only (not exported) |
|
|
60
|
+
|
|
61
|
+
Import from the public package surface — do not deep-import `src/lib/...` paths.
|
|
62
|
+
|
|
63
|
+
New `dga-*` custom elements must also be listed in `@a.nemreen/dga-tokens` `styles/host-compat.css` (`:is(...)`) so host-app `*` / `a` resets cannot flatten them.
|
|
64
|
+
|
|
65
|
+
### Secondary entry points
|
|
66
|
+
|
|
67
|
+
Heavier shell pieces ship as separate FESMs so the primary bundle stays lean:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { DgaHeader } from '@a.nemreen/dga-ui/header';
|
|
71
|
+
import { DgaCookies } from '@a.nemreen/dga-ui/cookies';
|
|
72
|
+
import { DgaDatePicker } from '@a.nemreen/dga-ui/date-picker';
|
|
73
|
+
import { DgaChart } from '@a.nemreen/dga-ui/chart';
|
|
74
|
+
import { DgaChatbot } from '@a.nemreen/dga-ui/chatbot';
|
|
75
|
+
import { DgaPageTransition } from '@a.nemreen/dga-ui/page-transition';
|
|
76
|
+
import { DGA_SAUDI_CITIES } from '@a.nemreen/dga-ui/saudi-cities';
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Accessibility tools live in a separate package — [`@a.nemreen/a11y`](https://www.npmjs.com/package/@a.nemreen/a11y) — mount with `Accessibility.mount()`.
|
|
80
|
+
|
|
81
|
+
## Setup
|
|
82
|
+
|
|
83
|
+
```css
|
|
84
|
+
@import 'tailwindcss';
|
|
85
|
+
@import '@a.nemreen/dga-tokens/styles.css';
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Keep existing app resets (`* { margin: 0; padding: 0 }`, `a { color: var(--color-mainColor) }`). Tokens ship unlayered `host-compat.css` (last in `styles.css`) so DGA components win those globals. New `dga-*` tags must be added to that `:is()` list. Optional: wrap leftover host CSS in `@layer base` so *your* Tailwind utilities also win — see the tokens README.
|
|
89
|
+
|
|
90
|
+
Load Arabic Google Fonts (IBM Plex default; see `@a.nemreen/dga-tokens` README / `DgaFontService`).
|
|
91
|
+
|
|
92
|
+
Scan library sources so Tailwind keeps component utilities (path may vary):
|
|
93
|
+
|
|
94
|
+
```css
|
|
95
|
+
@source "../node_modules/@a.nemreen/dga-ui/**/*.{mjs,js}";
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import {
|
|
100
|
+
DgaButton,
|
|
101
|
+
DgaInput,
|
|
102
|
+
DgaLabel,
|
|
103
|
+
DgaBadge,
|
|
104
|
+
DgaAlert,
|
|
105
|
+
DgaCheckbox,
|
|
106
|
+
DgaRadio,
|
|
107
|
+
DgaSelect,
|
|
108
|
+
DgaNativeSelect,
|
|
109
|
+
DgaField,
|
|
110
|
+
DgaSpinner,
|
|
111
|
+
DgaDialog,
|
|
112
|
+
DgaToast,
|
|
113
|
+
DgaCard,
|
|
114
|
+
DgaDivider,
|
|
115
|
+
DgaIcon,
|
|
116
|
+
DgaTable,
|
|
117
|
+
DgaBottomSheet,
|
|
118
|
+
DgaPopover,
|
|
119
|
+
DgaThemeToggle,
|
|
120
|
+
DgaLocaleToggle,
|
|
121
|
+
} from '@a.nemreen/dga-ui';
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Components
|
|
125
|
+
|
|
126
|
+
### Icon
|
|
127
|
+
|
|
128
|
+
Two layers, both HugeIcons Stroke Rounded (DGA / Platforms Code family):
|
|
129
|
+
|
|
130
|
+
1. **Chrome** — curated inline SVG via `name` (paints with the first frame; use in buttons, fields, menus).
|
|
131
|
+
2. **Content** — optional font via `glyph` (opt into `@a.nemreen/dga-tokens/styles/icon-font.css`).
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<!-- Chrome (always available) -->
|
|
135
|
+
<dga-icon name="search" size="sm" />
|
|
136
|
+
<dga-icon name="arrowNext" size="sm" label="التالي" />
|
|
137
|
+
<dga-icon name="riyal" size="md" />
|
|
138
|
+
|
|
139
|
+
<!-- Content (requires icon-font.css) -->
|
|
140
|
+
<dga-icon glyph="search-01" size="xl" />
|
|
141
|
+
<dga-icon glyph="notification-02" size="xl" tone="primary" />
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Use `arrowNext` / `arrowPrev` for forward/back — they mirror under `dir="rtl"`. Prefer literal `arrowLeft` / `arrowRight` only when you mean that physical direction.
|
|
145
|
+
|
|
146
|
+
Sizes (px): `2xs` 10 · `xs` 14 · `sm` 16 · `md` 18 · `lg` 20 · `xl` 24 · `2xl` 28 · `3xl` 32.
|
|
147
|
+
|
|
148
|
+
`DgaIcon` inlines a small HugeIcons core map (close / menu / search / chevrons / check / user / …) and lazy-loads the curated catalog on the first non-core `name`. Apps can add icons without forking the library:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
import { provideDgaIcons } from '@a.nemreen/dga-ui';
|
|
152
|
+
|
|
153
|
+
bootstrapApplication(App, {
|
|
154
|
+
providers: [
|
|
155
|
+
provideDgaIcons({
|
|
156
|
+
myBrand: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">…</svg>`,
|
|
157
|
+
}),
|
|
158
|
+
],
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
```html
|
|
163
|
+
<dga-icon name="myBrand" size="md" />
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Source: `@hugeicons/core-free-icons` (same family as design.dga.gov.sa). Regenerate with `node scripts/generate-dga-icons.mjs`.
|
|
167
|
+
|
|
168
|
+
### Scroll to top
|
|
169
|
+
|
|
170
|
+
Floating control that appears after the page scrolls past a threshold. Mount once at the app root; it stacks above `@a.nemreen/a11y` by default.
|
|
171
|
+
|
|
172
|
+
```html
|
|
173
|
+
<dga-scroll-top position="end" [threshold]="320" />
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Button
|
|
177
|
+
|
|
178
|
+
```html
|
|
179
|
+
<button dgaButton type="button">حفظ</button>
|
|
180
|
+
<button dgaButton variant="outline" size="sm">إلغاء</button>
|
|
181
|
+
<button dgaButton variant="danger" disabled>حذف</button>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Input + Label + Field
|
|
185
|
+
|
|
186
|
+
```html
|
|
187
|
+
<label dgaLabel dgaRequired for="email">البريد</label>
|
|
188
|
+
<input dgaInput id="email" type="email" />
|
|
189
|
+
<textarea dgaInput rows="3"></textarea>
|
|
190
|
+
|
|
191
|
+
<dga-field label="البريد" controlId="email" required hint="لن نشارك بريدك.">
|
|
192
|
+
<input dgaInput id="email" type="email" />
|
|
193
|
+
</dga-field>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Select
|
|
197
|
+
|
|
198
|
+
Configurable select (search, multi, always-open):
|
|
199
|
+
|
|
200
|
+
```html
|
|
201
|
+
<dga-select [options]="cities" [(value)]="city" />
|
|
202
|
+
<dga-select searchable [options]="cities" [(value)]="city" />
|
|
203
|
+
<dga-select multiple [options]="cities" [(value)]="cities" />
|
|
204
|
+
<dga-select multiple searchable [options]="cities" [(value)]="cities" />
|
|
205
|
+
<dga-select openMode="always" [options]="cities" [(value)]="city" />
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Native `<select>` styling for simple forms:
|
|
209
|
+
|
|
210
|
+
```html
|
|
211
|
+
<select dgaSelect>
|
|
212
|
+
<option value="riyadh">الرياض</option>
|
|
213
|
+
</select>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Checkbox + Radio
|
|
217
|
+
|
|
218
|
+
```html
|
|
219
|
+
<label>
|
|
220
|
+
<input dgaCheckbox type="checkbox" />
|
|
221
|
+
أوافق
|
|
222
|
+
</label>
|
|
223
|
+
|
|
224
|
+
<label>
|
|
225
|
+
<input dgaRadio type="radio" name="plan" value="basic" />
|
|
226
|
+
أساسية
|
|
227
|
+
</label>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Badge
|
|
231
|
+
|
|
232
|
+
```html
|
|
233
|
+
<dga-badge variant="success">مكتمل</dga-badge>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Alert
|
|
237
|
+
|
|
238
|
+
```html
|
|
239
|
+
<dga-alert variant="warning" title="تنبيه">تحقق من البيانات.</dga-alert>
|
|
240
|
+
<dga-alert dismissible (dismissed)="onDismiss()">يمكن إغلاقه</dga-alert>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Spinner
|
|
244
|
+
|
|
245
|
+
```html
|
|
246
|
+
<dga-spinner />
|
|
247
|
+
<dga-spinner size="lg" tone="neutral" />
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Preloader (optional first-load)
|
|
251
|
+
|
|
252
|
+
Full-screen brand overlay; auto-hides when the document is ready and `minDuration` elapses. Omit the tag if you do not want it.
|
|
253
|
+
|
|
254
|
+
```html
|
|
255
|
+
<dga-preloader
|
|
256
|
+
brand="بوابة الخدمات"
|
|
257
|
+
label="جاري التحميل"
|
|
258
|
+
[minDuration]="1000"
|
|
259
|
+
[once]="true"
|
|
260
|
+
persist="local"
|
|
261
|
+
/>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
- `once` + `persist="local"` - show only on the visitor’s first visit
|
|
265
|
+
- `persist="session"` - once per tab session
|
|
266
|
+
- `persist="none"` or `[once]="false"` - every load
|
|
267
|
+
- Optional `logoSrc` replaces the default geometric mark
|
|
268
|
+
- `(closed)` fires after the exit animation
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
import { DgaPreloader } from '@a.nemreen/dga-ui';
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Dialog
|
|
275
|
+
|
|
276
|
+
```html
|
|
277
|
+
<dga-dialog [(open)]="open" title="تأكيد">
|
|
278
|
+
<p>هل أنت متأكد؟</p>
|
|
279
|
+
<div dgaDialogActions>
|
|
280
|
+
<button dgaButton variant="ghost" (click)="open = false">إلغاء</button>
|
|
281
|
+
<button dgaButton (click)="confirm()">تأكيد</button>
|
|
282
|
+
</div>
|
|
283
|
+
</dga-dialog>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Modal
|
|
287
|
+
|
|
288
|
+
```html
|
|
289
|
+
<dga-modal
|
|
290
|
+
[(open)]="open"
|
|
291
|
+
title="تفاصيل الطلب"
|
|
292
|
+
description="راجع البيانات قبل المتابعة"
|
|
293
|
+
size="lg"
|
|
294
|
+
animation="scale"
|
|
295
|
+
>
|
|
296
|
+
<p>محتوى النافذة المنبثقة.</p>
|
|
297
|
+
<div dgaModalActions>
|
|
298
|
+
<button dgaButton variant="ghost" (click)="open = false">إلغاء</button>
|
|
299
|
+
<button dgaButton (click)="confirm()">تأكيد</button>
|
|
300
|
+
</div>
|
|
301
|
+
</dga-modal>
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Toast
|
|
305
|
+
|
|
306
|
+
```html
|
|
307
|
+
<dga-toast [(open)]="show" variant="success" title="تم">حُفظ السجل.</dga-toast>
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Tooltip / Switch / Progress / Nav (Wave I)
|
|
311
|
+
|
|
312
|
+
```html
|
|
313
|
+
<dga-switch [(checked)]="on" label="الإشعارات" />
|
|
314
|
+
<a dgaLink href="#">رابط</a>
|
|
315
|
+
<dga-progress [value]="60" />
|
|
316
|
+
<dga-skeleton />
|
|
317
|
+
<dga-skeleton [lines]="3" animation="shimmer" />
|
|
318
|
+
<dga-skeleton shape="circle" size="lg" />
|
|
319
|
+
<dga-tooltip title="مساعدة" text="وصف مختصر">
|
|
320
|
+
<button dgaButton size="sm">؟</button>
|
|
321
|
+
</dga-tooltip>
|
|
322
|
+
|
|
323
|
+
<dga-breadcrumb [items]="[{ label: 'الرئيسية', href: '#' }, { label: 'الحالي' }]" />
|
|
324
|
+
<dga-tabs [(selected)]="tab">
|
|
325
|
+
<dga-tab value="a" label="أ">...</dga-tab>
|
|
326
|
+
</dga-tabs>
|
|
327
|
+
<dga-content-switcher [(selected)]="view">
|
|
328
|
+
<dga-content-switcher-panel value="all" label="الكل">...</dga-content-switcher-panel>
|
|
329
|
+
</dga-content-switcher>
|
|
330
|
+
<dga-accordion>
|
|
331
|
+
<dga-accordion-item title="سؤال">جواب</dga-accordion-item>
|
|
332
|
+
</dga-accordion>
|
|
333
|
+
<dga-pagination [(page)]="page" [totalPages]="10" />
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Layout recipes
|
|
337
|
+
|
|
338
|
+
Prefer DGA spacing tokens (`gap-md`, `p-xl`, `py-3xl`) over raw pixel values. For page width, use `max-w-(--container-*)` - plain `max-w-5xl` binds to the spacing scale in Tailwind v4.
|
|
339
|
+
|
|
340
|
+
### Stack (column)
|
|
341
|
+
|
|
342
|
+
```html
|
|
343
|
+
<div class="flex flex-col gap-md">
|
|
344
|
+
<p>صف واحد</p>
|
|
345
|
+
<p>صف آخر</p>
|
|
346
|
+
</div>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Inline row
|
|
350
|
+
|
|
351
|
+
```html
|
|
352
|
+
<div class="flex flex-wrap items-center gap-md">
|
|
353
|
+
<button dgaButton>حفظ</button>
|
|
354
|
+
<button dgaButton variant="ghost">إلغاء</button>
|
|
355
|
+
</div>
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Split (space between)
|
|
359
|
+
|
|
360
|
+
```html
|
|
361
|
+
<div class="flex items-center justify-between gap-xl">
|
|
362
|
+
<h2 class="text-display-sm">العنوان</h2>
|
|
363
|
+
<div class="flex gap-sm">…</div>
|
|
364
|
+
</div>
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Responsive grid
|
|
368
|
+
|
|
369
|
+
```html
|
|
370
|
+
<div class="grid grid-cols-1 gap-lg md:grid-cols-2 lg:grid-cols-3">
|
|
371
|
+
<dga-card title="أ">…</dga-card>
|
|
372
|
+
<dga-card title="ب">…</dga-card>
|
|
373
|
+
<dga-card title="ج">…</dga-card>
|
|
374
|
+
</div>
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Or use the thin wrapper:
|
|
378
|
+
|
|
379
|
+
```html
|
|
380
|
+
<dga-grid [cols]="3" gap="lg">
|
|
381
|
+
<dga-card title="أ">…</dga-card>
|
|
382
|
+
<dga-card title="ب">…</dga-card>
|
|
383
|
+
<dga-card title="ج">…</dga-card>
|
|
384
|
+
</dga-grid>
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Contained section
|
|
388
|
+
|
|
389
|
+
```html
|
|
390
|
+
<dga-section title="القسم" subtitle="وصف قصير" contained>
|
|
391
|
+
محتوى القسم
|
|
392
|
+
</dga-section>
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Portal home shell (consumable across apps)
|
|
396
|
+
|
|
397
|
+
Compose the official home template with library primitives only - no page-local CSS required:
|
|
398
|
+
|
|
399
|
+
```html
|
|
400
|
+
<dga-top-bar registrationId="00000000000" />
|
|
401
|
+
|
|
402
|
+
<dga-header
|
|
403
|
+
appearance="portal"
|
|
404
|
+
mobileNav="sheet"
|
|
405
|
+
brand="شعار المنصة"
|
|
406
|
+
brandSlogan="بوابة الجهة"
|
|
407
|
+
brandHref="/"
|
|
408
|
+
[items]="navItems"
|
|
409
|
+
[actions]="headerActions"
|
|
410
|
+
(actionClick)="onAction($event)"
|
|
411
|
+
/>
|
|
412
|
+
<!-- mobileNav: sheet | fullscreen | push -->
|
|
413
|
+
|
|
414
|
+
<dga-hero appearance="portal" [slides]="heroSlides" [(activeIndex)]="i" />
|
|
415
|
+
|
|
416
|
+
<dga-section
|
|
417
|
+
width="wide"
|
|
418
|
+
tone="surface"
|
|
419
|
+
title="قسم من نحن"
|
|
420
|
+
subtitle="…"
|
|
421
|
+
>
|
|
422
|
+
<button dgaSectionActions dgaButton variant="outline">إجراء ثانوي</button>
|
|
423
|
+
<dga-grid [cols]="4" gap="xl">
|
|
424
|
+
<dga-metric appearance="stat" value="1.5M" label="شخص">
|
|
425
|
+
<dga-icon-badge dgaMetricIcon>
|
|
426
|
+
<dga-icon name="user" tone="primary" />
|
|
427
|
+
</dga-icon-badge>
|
|
428
|
+
</dga-metric>
|
|
429
|
+
</dga-grid>
|
|
430
|
+
</dga-section>
|
|
431
|
+
|
|
432
|
+
<dga-card title="عنوان البطاقة" description="نص إضافي">
|
|
433
|
+
<dga-icon-badge dgaCardLead>
|
|
434
|
+
<dga-icon name="home" tone="primary" />
|
|
435
|
+
</dga-icon-badge>
|
|
436
|
+
<div dgaCardActions>
|
|
437
|
+
<button dgaButton variant="outline" size="sm">اجراء ثانوي</button>
|
|
438
|
+
<button dgaButton size="sm">اجراء</button>
|
|
439
|
+
</div>
|
|
440
|
+
</dga-card>
|
|
441
|
+
|
|
442
|
+
<dga-card>
|
|
443
|
+
<dga-card-media dgaCardMedia alt="خبر" />
|
|
444
|
+
…
|
|
445
|
+
</dga-card>
|
|
446
|
+
|
|
447
|
+
<dga-logo-tile label="شريك" />
|
|
448
|
+
<dga-footer
|
|
449
|
+
appearance="brand"
|
|
450
|
+
[columns]="footerColumns"
|
|
451
|
+
[iconGroups]="footerIconGroups"
|
|
452
|
+
[bottomLinks]="footerBottomLinks"
|
|
453
|
+
[logos]="footerLogos"
|
|
454
|
+
copyright="جميع الحقوق محفوظة © 2026"
|
|
455
|
+
meta="آخر تحديث للموقع في 11 سبتمبر 2026 7:30 ص"
|
|
456
|
+
/>
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Portal tokens (layout sizes): `--size-hero-portal` (491px), `--size-header-portal` (72px), `--size-icon-badge` (40px), `--size-dot` (16px).
|
|
460
|
+
|
|
461
|
+
### Content + sticky aside
|
|
462
|
+
|
|
463
|
+
```html
|
|
464
|
+
<div class="mx-auto grid max-w-(--container-7xl) gap-3xl px-xl md:grid-cols-[1fr_auto]">
|
|
465
|
+
<main class="min-w-0">…</main>
|
|
466
|
+
<dga-side-info title="في هذه الصفحة" [items]="tocItems" />
|
|
467
|
+
</div>
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
## License
|
|
471
|
+
|
|
472
|
+
MIT — see [LICENSE](./LICENSE). Copyright (c) 2026 Ahmed Nemreen.
|
|
473
|
+
|
|
474
|
+
Use it in any project. **Do not rebrand and sell it as your own unique product.**
|