@hawiyah/vue 0.0.0-stage → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +73 -0
- package/NOTICE +19 -0
- package/PORTAL.md +70 -0
- package/README.md +388 -2
- package/dist/calendar.d.ts +183 -0
- package/dist/calendar.d.ts.map +1 -0
- package/dist/calendar.js +448 -0
- package/dist/calendar.js.map +1 -0
- package/dist/content-navigation.d.ts +61 -0
- package/dist/content-navigation.d.ts.map +1 -0
- package/dist/content-navigation.js +31 -0
- package/dist/content-navigation.js.map +1 -0
- package/dist/content.d.ts +392 -0
- package/dist/content.d.ts.map +1 -0
- package/dist/content.js +310 -0
- package/dist/content.js.map +1 -0
- package/dist/controls.d.ts +657 -0
- package/dist/controls.d.ts.map +1 -0
- package/dist/controls.js +679 -0
- package/dist/controls.js.map +1 -0
- package/dist/display.d.ts +387 -0
- package/dist/display.d.ts.map +1 -0
- package/dist/display.js +293 -0
- package/dist/display.js.map +1 -0
- package/dist/expansion-interactive.d.ts +476 -0
- package/dist/expansion-interactive.d.ts.map +1 -0
- package/dist/expansion-interactive.js +613 -0
- package/dist/expansion-interactive.js.map +1 -0
- package/dist/file-upload-list.d.ts +54 -0
- package/dist/file-upload-list.d.ts.map +1 -0
- package/dist/file-upload-list.js +21 -0
- package/dist/file-upload-list.js.map +1 -0
- package/dist/forms.d.ts +388 -0
- package/dist/forms.d.ts.map +1 -0
- package/dist/forms.js +156 -0
- package/dist/forms.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive.d.ts +240 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +341 -0
- package/dist/interactive.js.map +1 -0
- package/dist/layout.d.ts +755 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +101 -0
- package/dist/layout.js.map +1 -0
- package/dist/mobile-top-bar.d.ts +47 -0
- package/dist/mobile-top-bar.d.ts.map +1 -0
- package/dist/mobile-top-bar.js +18 -0
- package/dist/mobile-top-bar.js.map +1 -0
- package/dist/native-attributes.d.ts +38 -0
- package/dist/native-attributes.d.ts.map +1 -0
- package/dist/native-attributes.js +27 -0
- package/dist/native-attributes.js.map +1 -0
- package/dist/navigation-drawer.d.ts +87 -0
- package/dist/navigation-drawer.d.ts.map +1 -0
- package/dist/navigation-drawer.js +56 -0
- package/dist/navigation-drawer.js.map +1 -0
- package/dist/patterns.d.ts +455 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +355 -0
- package/dist/patterns.js.map +1 -0
- package/dist/portal.d.ts +174 -0
- package/dist/portal.d.ts.map +1 -0
- package/dist/portal.js +36 -0
- package/dist/portal.js.map +1 -0
- package/dist/search-field.d.ts +87 -0
- package/dist/search-field.d.ts.map +1 -0
- package/dist/search-field.js +123 -0
- package/dist/search-field.js.map +1 -0
- package/dist/shared.d.ts +46 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +40 -0
- package/dist/shared.js.map +1 -0
- package/dist/site-verification.d.ts +63 -0
- package/dist/site-verification.d.ts.map +1 -0
- package/dist/site-verification.js +34 -0
- package/dist/site-verification.js.map +1 -0
- package/package.json +53 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
|
10
|
+
|
|
11
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
|
12
|
+
|
|
13
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
|
14
|
+
|
|
15
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
|
16
|
+
|
|
17
|
+
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
|
18
|
+
|
|
19
|
+
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
|
20
|
+
|
|
21
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
|
22
|
+
|
|
23
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
|
24
|
+
|
|
25
|
+
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
|
26
|
+
|
|
27
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
|
28
|
+
|
|
29
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
|
30
|
+
|
|
31
|
+
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
|
32
|
+
|
|
33
|
+
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
|
34
|
+
|
|
35
|
+
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
|
36
|
+
|
|
37
|
+
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
|
|
38
|
+
|
|
39
|
+
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
|
40
|
+
|
|
41
|
+
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
|
42
|
+
|
|
43
|
+
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
|
44
|
+
|
|
45
|
+
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
|
46
|
+
|
|
47
|
+
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
|
48
|
+
|
|
49
|
+
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
|
50
|
+
|
|
51
|
+
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
|
52
|
+
|
|
53
|
+
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
|
54
|
+
|
|
55
|
+
END OF TERMS AND CONDITIONS
|
|
56
|
+
|
|
57
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
58
|
+
|
|
59
|
+
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
|
60
|
+
|
|
61
|
+
Copyright [yyyy] [name of copyright owner]
|
|
62
|
+
|
|
63
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
64
|
+
you may not use this file except in compliance with the License.
|
|
65
|
+
You may obtain a copy of the License at
|
|
66
|
+
|
|
67
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
68
|
+
|
|
69
|
+
Unless required by applicable law or agreed to in writing, software
|
|
70
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
71
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
72
|
+
See the License for the specific language governing permissions and
|
|
73
|
+
limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Hawiyah — هوية
|
|
2
|
+
|
|
3
|
+
تم التطوير بواسطة فريق التطوير في قطاع المنصات الوطنية - مركز المعلومات الوطني
|
|
4
|
+
Developed by the Development Team in the National Platforms Sector — National Information Center.
|
|
5
|
+
|
|
6
|
+
Copyright 2026 Mohamed Embarak
|
|
7
|
+
|
|
8
|
+
Licensed under the Apache License, Version 2.0. See LICENSE.
|
|
9
|
+
|
|
10
|
+
This distribution includes an Umm al-Qura calendar table derived from
|
|
11
|
+
HijriDate 2.3.0, Copyright (c) 2018 Mohammed Alshehri, licensed under MIT.
|
|
12
|
+
The full notice and provenance are in packages/core/third-party in the
|
|
13
|
+
source repository and third-party in the core package.
|
|
14
|
+
|
|
15
|
+
Brand source fonts are licensed separately under the SIL Open Font License
|
|
16
|
+
1.1. The unmodified notices accompany their files in brand/third-party.
|
|
17
|
+
Font software and third-party dependencies retain their own licenses.
|
|
18
|
+
The Hawiyah name and identity do not imply endorsement by Saudi Arabia's
|
|
19
|
+
Digital Government Authority. Apache 2.0 does not grant trademark rights.
|
package/PORTAL.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Portal layout
|
|
2
|
+
|
|
3
|
+
`PortalLayout` composes `PortalHeader`, optional `SecondaryNav`, `Breadcrumb`,
|
|
4
|
+
a focusable main container and `PortalFooter`. It defaults to `lang="ar" dir="rtl"`.
|
|
5
|
+
|
|
6
|
+
```vue
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import { PortalLayout } from '@hawiyah/vue';
|
|
9
|
+
import '@hawiyah/styles/styles.css';
|
|
10
|
+
const links = [{ label: 'الخدمات', href: '/services', current: true }];
|
|
11
|
+
</script>
|
|
12
|
+
<template>
|
|
13
|
+
<PortalLayout brand="هوية" :links="links" :secondary-navigation="links"
|
|
14
|
+
:breadcrumbs="[{ label: 'الرئيسية', href: '/' }, { label: 'الخدمات', current: true }]"
|
|
15
|
+
:footer-links="[{ label: 'الخصوصية', href: '/privacy' }]">
|
|
16
|
+
<h1>الخدمات</h1>
|
|
17
|
+
</PortalLayout>
|
|
18
|
+
</template>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Props: `brand` (required), `homeHref`, `links`, `secondaryNavigation`, `footerLinks`,
|
|
22
|
+
`breadcrumbs`, `copyright`, `mainId`, `lang`, `dir`. Accessible labels:
|
|
23
|
+
`skipLabel`, `menuLabel`, `navigationLabel`, `secondaryLabel`, `breadcrumbLabel`,
|
|
24
|
+
`footerLabel`. `mainId` uses Vue `useId` by default. Slots: `logo`, `actions`,
|
|
25
|
+
`footer`, default (page content). Supply actual artwork through `logo`.
|
|
26
|
+
|
|
27
|
+
For English, pass `lang="en" dir="ltr"` and translate all content and labels.
|
|
28
|
+
Direction and language remain independent. Existing standalone `PortalHeader`
|
|
29
|
+
keeps `brand`, `homeHref`, `links`, `navLabel` and its slots, adding `menuLabel`,
|
|
30
|
+
`navigationId`, `mainId` and `skipLabel`. Escape returns focus to the toggle;
|
|
31
|
+
selection, outside press and focus leaving close the mobile disclosure. Tab is
|
|
32
|
+
native. Desktop links remain visible. `SecondaryNav` uses `items`, `label` and
|
|
33
|
+
ordinary page links with `aria-current`, not menu/tablist semantics.
|
|
34
|
+
|
|
35
|
+
The 48rem mobile breakpoint is Hawiyah policy. Shared tokens preserve DGA, Hawiyah
|
|
36
|
+
and custom themes. The shell introduces no animations. Source-informed
|
|
37
|
+
composition does not establish pixel parity or DGA certification.
|
|
38
|
+
|
|
39
|
+
## Mobile navigation bar
|
|
40
|
+
|
|
41
|
+
Use `variant="mobile"` on `SecondaryNav` (React/Vue) or `hw-secondary-nav`
|
|
42
|
+
(Angular). Items accept an optional decorative `icon` name from the bundled icon
|
|
43
|
+
stylesheet, such as `home-01`, `search-01` or `menu-01`; labels remain required.
|
|
44
|
+
Vanilla uses `data-variant="mobile"` and the same semantic HTML:
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<nav class="hw-secondary-nav" data-variant="mobile" aria-label="تنقل الجوال">
|
|
48
|
+
<ul>
|
|
49
|
+
<li><a href="/" aria-current="page"><span class="hw-icon" data-icon="home-01" aria-hidden="true"></span><span>الرئيسية</span></a></li>
|
|
50
|
+
<li><a href="/services"><span class="hw-icon" data-icon="search-01" aria-hidden="true"></span><span>الخدمات</span></a></li>
|
|
51
|
+
</ul>
|
|
52
|
+
</nav>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The bar uses equal-width items, 24 px icons, a 70 px minimum height, wrapped labels
|
|
56
|
+
and a top current-page indicator. It is in normal flow and does not cover page
|
|
57
|
+
content. Safe-area bottom padding accommodates mobile devices; the source OS
|
|
58
|
+
home indicator is not reproduced. The application owns route/current updates.
|
|
59
|
+
These are page links, not content tabs: preserve native Tab/Enter navigation.
|
|
60
|
+
|
|
61
|
+
DGA/custom color transitions use `--hw-duration-tab-bar: 300ms` and
|
|
62
|
+
`--hw-ease-tab-bar: cubic-bezier(0, 0, 0.58, 1)`. Hawiyah remains immediate by
|
|
63
|
+
default. Reduced motion removes transitions; forced colors retains the selected
|
|
64
|
+
top border and keyboard focus. Hover does not mark a route selected.
|
|
65
|
+
|
|
66
|
+
Source Mobile `8332:24202` → `8332:24242` → `8332:24282` supports color changes,
|
|
67
|
+
not a sliding indicator or tab-panel animation. Semantic colors adapt to theme;
|
|
68
|
+
icon color follows the label, since imported icon override endpoints were not
|
|
69
|
+
resolved. Arabic width differs from English in the source, so no fixed item
|
|
70
|
+
width is imposed. This is a source-informed composition, not certified parity.
|
package/README.md
CHANGED
|
@@ -1,3 +1,389 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @hawiyah/vue
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Native Vue 3 components for Hawiyah — هوية, a UI library built to comply with the
|
|
4
|
+
DGA Platforms Code.
|
|
5
|
+
Install with `npm install @hawiyah/styles @hawiyah/vue`. This is a pre-1.0 release,
|
|
6
|
+
so a minor version may still change its API. Import the shared CSS once:
|
|
7
|
+
|
|
8
|
+
```vue
|
|
9
|
+
<script setup lang="ts">
|
|
10
|
+
import { ref } from "vue";
|
|
11
|
+
import { Button, Combobox, Dialog, TextField } from "@hawiyah/vue";
|
|
12
|
+
import "@hawiyah/styles/styles.css";
|
|
13
|
+
// Optional for a new application: import '@hawiyah/styles/reset.css';
|
|
14
|
+
const name = ref("");
|
|
15
|
+
const city = ref("");
|
|
16
|
+
const reviewing = ref(false);
|
|
17
|
+
const cities = [{ value: "riyadh", label: "الرياض" }];
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<form dir="rtl" lang="ar" @submit.prevent="reviewing = true">
|
|
22
|
+
<TextField v-model="name" label="الاسم" name="name" required />
|
|
23
|
+
<Combobox
|
|
24
|
+
v-model="city"
|
|
25
|
+
:options="cities"
|
|
26
|
+
label="المدينة"
|
|
27
|
+
name="city"
|
|
28
|
+
required
|
|
29
|
+
empty-message="لا توجد نتائج"
|
|
30
|
+
required-message="اختر مدينة من القائمة."
|
|
31
|
+
:results-message="(count) => `${count} نتائج متاحة`"
|
|
32
|
+
/>
|
|
33
|
+
<Button type="submit">مراجعة</Button>
|
|
34
|
+
</form>
|
|
35
|
+
<Dialog v-model:open="reviewing" title="مراجعة الطلب" close-label="إغلاق">
|
|
36
|
+
<p>{{ name }}</p>
|
|
37
|
+
<template #footer="{ close }"><Button @click="close">تم</Button></template>
|
|
38
|
+
</Dialog>
|
|
39
|
+
</template>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Conventions
|
|
43
|
+
|
|
44
|
+
Components use native elements and Vue rendering. They share core keyboard and
|
|
45
|
+
combobox transitions without importing another adapter. Vue `useId()` supplies
|
|
46
|
+
server/client stable accessible IDs; importing or server-rendering the package
|
|
47
|
+
does not access browser globals. Vue 3.5+ and native `<dialog>` support are required.
|
|
48
|
+
A server-rendered open dialog becomes modal after mounting.
|
|
49
|
+
|
|
50
|
+
Native attributes and event listeners fall through to the primary control. Classes
|
|
51
|
+
are merged, and internal event handlers preserve consumer listeners. Field controls
|
|
52
|
+
expose `element` and `focus()` through a Vue template ref; `Button` does too.
|
|
53
|
+
`Dialog` exposes `element`, `show()` and `close()`. `Combobox` adds `close()`.
|
|
54
|
+
|
|
55
|
+
Text inputs, select, combobox, tabs and pagination use `v-model`; omitting it
|
|
56
|
+
uses internal state initialized by `defaultValue`. Checkbox/switch values are
|
|
57
|
+
booleans; radio values are strings matched against the radio's `value` prop.
|
|
58
|
+
`Dialog` uses `v-model:open` / `defaultOpen`. Form reset emits model defaults so
|
|
59
|
+
both controlled and uncontrolled controls can return to their initial state.
|
|
60
|
+
Use `defaultValue` alongside `v-model` if a nonempty reset value is desired.
|
|
61
|
+
|
|
62
|
+
For radios sharing a form and `name`, set `defaultValue` to the option that
|
|
63
|
+
should be checked after a reset. The group emits that value once. A group
|
|
64
|
+
without a checked default resets to an empty string.
|
|
65
|
+
|
|
66
|
+
Locale, direction, theme, mode and density are independent application choices.
|
|
67
|
+
Set `lang`, `dir`, `data-hw-theme="hawiyah|dga|custom"`,
|
|
68
|
+
`data-hw-mode="light|dark"` and `data-hw-density="comfortable|compact|mobile"` on an
|
|
69
|
+
ancestor. Provide translated labels, status messages, pagination labels and
|
|
70
|
+
close labels; the library never infers text language from layout direction.
|
|
71
|
+
|
|
72
|
+
## Catalog
|
|
73
|
+
|
|
74
|
+
| Export | Main contract |
|
|
75
|
+
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
76
|
+
| `Button` | `variant`, `size`, `loading`; defaults to `type="button"` |
|
|
77
|
+
| `Field` | `label`, `hint`, `error`, `required`, `controlId`; provides association to a child field control; scoped default slot exposes IDs for native controls |
|
|
78
|
+
| `TextField`, `Textarea` | String `v-model`, `defaultValue`, field decoration; standard input/textarea attributes |
|
|
79
|
+
| `Select` | String `v-model`, `options: Option[]`; native option children also accepted |
|
|
80
|
+
| `Checkbox`, `Switch` | Boolean `v-model`, `defaultValue`, label/hint/error; checkbox supports `indeterminate` |
|
|
81
|
+
| `Radio` | String `v-model`, `value`, shared native `name`; group inside a fieldset with a legend |
|
|
82
|
+
| `Combobox` | String `v-model`, `options`, `disabled`, `readonly`, `emptyMessage`, `resultsMessage(count)`, `requiredMessage`; emits `update:query`, `update:open` |
|
|
83
|
+
| `Tabs` | `items`, required `label`, string `v-model`, `orientation`, `activationMode`, `overflow: menu/scroll` (default menu), configurable `overflowLabel`; item content or named value slots, optional `tab:value` label slots. Compact horizontal containers move excess labels into a keyboard-accessible disclosure; vertical tabs remain visible. |
|
|
84
|
+
| `Dialog` | `title`, `description`, `closeLabel`, `closeOnBackdrop`; default/footer slots receive `{close}`, trigger slot receives `{open}` |
|
|
85
|
+
| `Accordion` | `items: {value,title,content?,open?}[]`, `exclusive`; native details, named value content slots; emits `toggle(value,open)` |
|
|
86
|
+
| `Card` | `header`, default and `footer` slots |
|
|
87
|
+
| `Badge` | Static label; `tone="neutral\|success\|warning\|danger\|info"`, `variant="soft\|outline\|dot"`; [source and adaptations](../../docs/nic-badges.md). |
|
|
88
|
+
| `Alert` | `tone: info | success | warning | danger`, `title`; defaults to status, or alert for danger; native role can override |
|
|
89
|
+
| `Table` | `columns`, `rows`, `rowKey`, `caption`; column `{key,header,cell?,rowHeader?}`; named `cell:key` slots receive `{row,index}`; omit columns to compose native children |
|
|
90
|
+
| `Pagination` | Numeric `v-model`/`defaultValue`, `totalPages`, Arabic default `label`, `previousLabel`, `nextLabel`, `pageLabel(page)`, `formatPage(page)`, `siblingCount=1`, `disabled`, `hideOnSinglePage=false`. Ellipsis disclosures use `gapLabel(start,end)`, `jumpLabel`, `goLabel`; gaps above 100 pages use bounded integer entry. Parent fetches/slices data; no navigation or scrolling is imposed. |
|
|
91
|
+
| `Breadcrumb` | `items: {label,href?,current?}[]`, `label` |
|
|
92
|
+
| `Progress` | Required `label`, optional value for determinate mode, `max=100` |
|
|
93
|
+
| `Skeleton` | Decorative hidden span, size using native style/class |
|
|
94
|
+
| `Spinner` | Status with localized `label` |
|
|
95
|
+
| `Avatar` | Required `name`; optional `src`, `initials`, `size="40\|64\|80\|120\|sm\|md\|lg\|xl"`, `variant="circle\|square"`. Failed images fall back to initials; changing `src` retries. [Source notes](../../docs/nic-avatars.md). |
|
|
96
|
+
| `Divider` | Native `hr` |
|
|
97
|
+
| `Tooltip` | Plain `content`, one focusable trigger in default slot; description IDs merge with the trigger |
|
|
98
|
+
| `FileUpload` | Native input attributes plus field decoration; emits `update:files(File[])`; optional default slot |
|
|
99
|
+
| `Stepper` | `items: {value,label,description?,status?}[]`, `current`, `label` |
|
|
100
|
+
| `EmptyState` | `title`, `description`; `icon`, default, `action` slots |
|
|
101
|
+
|
|
102
|
+
`Field` associates one control; use a native fieldset and legend for groups.
|
|
103
|
+
Combobox is local, editable, single selection: editing clears the submitted value,
|
|
104
|
+
arrow keys skip disabled options, Enter commits explicitly, Escape/Tab/blur/outside
|
|
105
|
+
close without committing. `name` is attached to a hidden input containing the
|
|
106
|
+
selected option value. Required validation checks selection, not merely typed text.
|
|
107
|
+
Readonly comboboxes never open or change selection. Tabs use roving focus and
|
|
108
|
+
RTL-aware horizontal arrows; manual mode selects through native Enter/Space.
|
|
109
|
+
Dialog uses `showModal()` / `close()` for browser modality and focus containment,
|
|
110
|
+
then returns focus to its connected opener. Tooltips must not contain interactive
|
|
111
|
+
content; use a dialog for interactive help.
|
|
112
|
+
|
|
113
|
+
The example in `examples/vue` includes independent locale/direction/theme controls,
|
|
114
|
+
a conditional service form, validation, native modal review, local request filtering
|
|
115
|
+
and pagination, and the remaining presentation components. Unit tests exercise
|
|
116
|
+
behavior and server rendering; browser checks validate the application workflow.
|
|
117
|
+
|
|
118
|
+
## Expanded controls
|
|
119
|
+
|
|
120
|
+
The package now exports **77 components**: the original 27 and these 50 additions.
|
|
121
|
+
All use native Vue rendering, shared CSS, and the same attrs/slots conventions.
|
|
122
|
+
|
|
123
|
+
| Component | Props, models and events |
|
|
124
|
+
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
125
|
+
| `InputGroup` | `prefix`, default and `suffix` slots; the consuming field supplies its label |
|
|
126
|
+
| `PasswordField` | String `v-model`, `defaultValue`, field decoration, `disabled`, `readonly`; `showLabel`, `hideLabel` localize the reveal button; input and button form one input group |
|
|
127
|
+
| `SearchField` | String `v-model`, `defaultValue`, field decoration, `clearLabel`; optional `suggestions`, `maxSuggestions` (8), `resultsMessage(count)`, `showSearchButton` (false), `searchLabel`; emits `search(query)`. Input attributes and exposed `element`/`focus()` remain supported. |
|
|
128
|
+
| `NumberField` | `v-model: number \| ''`; native `min`, `max`, `step` and `required`; clearing preserves an empty value instead of inventing zero |
|
|
129
|
+
| `Slider` | Numeric `v-model`, `defaultValue`, `min=0`, `max=100`, `step=1`, field decoration, `disabled`, `readonly`; native range keyboard behavior |
|
|
130
|
+
| `RangeSlider` | Tuple `v-model: readonly [number,number]`, `defaultValue`, `min`, `max`, `step`; `label`, `lowerLabel`, `upperLabel`, `lowerName`, `upperName`; two native ranges enforce lower ≤ upper |
|
|
131
|
+
| `Rating` | Numeric `v-model`, `defaultValue`, `max=5` (1–20), native `name`, `required`, `label`, `hint`, `error`, `disabled`, `readonly`; `optionLabel(value,max)` localizes each native radio |
|
|
132
|
+
| `RatingDisplay` | Required `label`, numeric `value=0`, `max=5` (1–20), `showValue=true`, `valueLabel(value,max)`; noninteractive fractional aggregate score with one accessible image name. |
|
|
133
|
+
| `PinInput` | String `v-model`, `length=6`, field decoration; one input with `one-time-code`, numeric keyboard, native length/pattern; normalizes Arabic-Indic/Eastern digits; emits `complete(value)` |
|
|
134
|
+
| `TagInput` | String-array `v-model`, `defaultValue`, `name`, `required`, field decoration; Enter/comma adds unique trimmed tags; Backspace on an empty draft removes the last tag; `removeLabel(value)`, `requiredMessage` |
|
|
135
|
+
| `MultiSelect` | String-array `v-model`, `defaultValue`, `options`, `label`, `searchLabel`, `emptyMessage`, `requiredMessage`; normalized search and native checkboxes, repeated hidden values for `name`; no combobox role |
|
|
136
|
+
| `Calendar` | ISO-string `v-model`, `defaultValue`, `month`, `min`, `max`, `locale`, `calendar`, `weekStartsOn`, `isDateDisabled(value)`; `label`, `previousLabel`, `nextLabel`, `unsupportedMessage`; emits `update:month` when browsing |
|
|
137
|
+
| `DatePicker` | Calendar props plus field decoration and string `v-model`; custom ISO text input and modal Calendar; `v-model:calendar` switches `gregory` / `islamic-umalqura` while preserving ISO value; `calendarSwitchable=true`, `calendarSystemLabel`, `gregoryLabel`, `hijriLabel`, `calendarLabel`, `openLabel`, `closeLabel`, `invalidMessage` |
|
|
138
|
+
| `FileDropzone` | Field decoration, native `name`/`form`, `accept`, `multiple`, `maxSize` in bytes, `disabled`, `readonly`, `dropLabel`; emits `update:files(File[])` and `reject(File[])`; valid drops populate the native file input, invalid batches clear it |
|
|
139
|
+
|
|
140
|
+
Value controls support form reset. Arrays reset to `defaultValue`; native file
|
|
141
|
+
controls reset to no files. `TagInput` and `MultiSelect` validate committed
|
|
142
|
+
selection rather than draft/search text. Supply localized validity messages.
|
|
143
|
+
Native attributes such as `name`, `form`, `autocomplete` and `inputmode` pass to
|
|
144
|
+
the control, except that compound controls explicitly manage successful values.
|
|
145
|
+
|
|
146
|
+
`TextField` remains available for standard HTML input types: `text`, `email`,
|
|
147
|
+
`url`, `tel`, `password`, `search`, `date`, `time`, `month`, `week`,
|
|
148
|
+
`datetime-local`, `color`, and others supported by the browser. It uses a string
|
|
149
|
+
model and preserves native input semantics. Use `NumberField` for numeric/empty
|
|
150
|
+
values, `FileUpload`/`FileDropzone` for File objects, and the native choice/range
|
|
151
|
+
components for their specialized models. Native date/time values are machine
|
|
152
|
+
values, independent of localized browser display; `datetime-local` contains no
|
|
153
|
+
time-zone information.
|
|
154
|
+
|
|
155
|
+
### Switching date systems
|
|
156
|
+
|
|
157
|
+
```vue
|
|
158
|
+
<script setup lang="ts">
|
|
159
|
+
import { ref } from "vue";
|
|
160
|
+
import { DatePicker } from "@hawiyah/vue";
|
|
161
|
+
import type { CalendarSystem } from "@hawiyah/core";
|
|
162
|
+
const date = ref("2024-03-11");
|
|
163
|
+
const system = ref<CalendarSystem>("islamic-umalqura");
|
|
164
|
+
</script>
|
|
165
|
+
|
|
166
|
+
<template>
|
|
167
|
+
<DatePicker
|
|
168
|
+
v-model="date"
|
|
169
|
+
v-model:calendar="system"
|
|
170
|
+
name="appointment"
|
|
171
|
+
label="تاريخ الموعد"
|
|
172
|
+
locale="ar-SA"
|
|
173
|
+
dir="rtl"
|
|
174
|
+
required
|
|
175
|
+
calendar-label="اختر تاريخ الموعد"
|
|
176
|
+
calendar-system-label="نوع التقويم"
|
|
177
|
+
gregory-label="ميلادي"
|
|
178
|
+
hijri-label="أم القرى"
|
|
179
|
+
open-label="فتح التقويم"
|
|
180
|
+
close-label="إغلاق"
|
|
181
|
+
previous-label="الشهر السابق"
|
|
182
|
+
next-label="الشهر التالي"
|
|
183
|
+
invalid-message="اختر تاريخاً متاحاً."
|
|
184
|
+
unsupported-message="التاريخ خارج نطاق بيانات تقويم أم القرى المدعومة."
|
|
185
|
+
/>
|
|
186
|
+
</template>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The default Arabic locale supplies calendar navigation, picker control labels and validation messages. Set `locale="en"` for English or override individual labels through props.
|
|
190
|
+
|
|
191
|
+
The stored/submitted value stays Gregorian `YYYY-MM-DD` when switching display
|
|
192
|
+
calendars. Reopening shows the selected date's month. Calendar supports arrows
|
|
193
|
+
(horizontal direction follows RTL/LTR), Home/End, PageUp/PageDown, and
|
|
194
|
+
Shift+PageUp/PageDown for years. Selection uses native Enter/Space button behavior.
|
|
195
|
+
Disabled dates are skipped, min/max are enforced, and readonly calendars allow
|
|
196
|
+
browsing without changing the selected value.
|
|
197
|
+
|
|
198
|
+
Saudi Umm al-Qura conversion and arithmetic come from the core's pinned Saudi
|
|
199
|
+
reference table, using `@internationalized/date` arithmetic. The supported range
|
|
200
|
+
is **AH 1343–1500, Gregorian 1924-08-01 through 2077-11-16**. Numeric day/year
|
|
201
|
+
values and accessible date names use the same provider through
|
|
202
|
+
`formatCalendarDate`; browser ICU supplies localized names and formatting, not
|
|
203
|
+
an alternative numeric conversion. Navigation stops at supported boundaries.
|
|
204
|
+
Switching an existing out-of-range Gregorian value does not rewrite it: the
|
|
205
|
+
picker displays the caller-localized unsupported message and native validation
|
|
206
|
+
rejects it until the user chooses a supported date or switches back. See the
|
|
207
|
+
core calendar documentation for provenance and coverage; this is not an official
|
|
208
|
+
endorsement or a claim about religious moon-sighting determinations.
|
|
209
|
+
|
|
210
|
+
## Expanded interactions
|
|
211
|
+
|
|
212
|
+
| Component | Contract |
|
|
213
|
+
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
214
|
+
| `ToggleGroup` | `options`, `label`, `variant: segmented\|outline`; string `v-model` uses native radio selection; `multiple` uses string-array `v-model` and pressed buttons; `defaultValue`, native `name`/`form`, `disabled`, `readonly` |
|
|
215
|
+
| `Popover` | `label`, `triggerLabel`, `v-model:open` / `defaultOpen`, `disabled`; optional trigger content slot; default slot `{close}`; labelled region, ordinary Tab navigation, outside press and Escape dismissal |
|
|
216
|
+
| `Menu` | `label`, `items: {value,label,disabled?,href?}[]`; optional trigger content slot; emits `select(value)`; Home/End/ArrowUp/ArrowDown skip disabled items, Escape returns focus, Tab exits normally |
|
|
217
|
+
| `Drawer` | Dialog API with `side: start\|end\|bottom`; modal native dialog and preserved trigger focus; default/footer/trigger scoped slots inherited |
|
|
218
|
+
| `ToastRegion` | `messages: {id,title?,message,tone?,urgent?,dismissible?}[]`, `label`, `dismissLabel(message)`, `@dismiss="remove"`. Set `variant="banner"` and optionally `position="inline"` or a corner. A dismissal listener enables the close action. Defaults are Arabic. |
|
|
219
|
+
| `Collapsible` | `label`, boolean `v-model`, `defaultValue`, `disabled`; native details/summary with default content slot |
|
|
220
|
+
| `TreeView` | `items: {id,label,disabled?,children?}[]`, `label`, selected-id `v-model`, `defaultValue`, `v-model:expanded`, `defaultExpanded`, `disabled`; localized `expandLabel(node)` / `collapseLabel(node)`; flattened visible tree with level/position, roving focus and RTL expansion arrows |
|
|
221
|
+
| `Carousel` | Required label/slides; `v-model/defaultValue`, `wrap=true`, `slides` and named slide-ID slots, one-based `slideMessage(index,total)`. `showIndicators=true`, localized control/indicator/description/empty labels, inert inactive slides, explicit navigation and no autoplay. [Source and motion notes](../../docs/nic-carousel.md). |
|
|
222
|
+
|
|
223
|
+
Popover is a disclosure, not a focus trap. Menu is for commands/navigation;
|
|
224
|
+
TreeView does not claim drag-and-drop. Toast and notification dismissal is
|
|
225
|
+
caller-owned: update the supplied message array in response to the emitted ID.
|
|
226
|
+
|
|
227
|
+
## Expanded content and platform patterns
|
|
228
|
+
|
|
229
|
+
| Component | Contract |
|
|
230
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
231
|
+
| `Link` | Native anchor attrs, `href`, `disabled`, `external`; external links use `noopener noreferrer` |
|
|
232
|
+
| `IconButton` | Required accessible `label`, `variant`, `size`, `disabled`, `loading`; default decorative icon slot |
|
|
233
|
+
| `ButtonGroup` | Required `label`; default buttons slot; native `data-variant` / `data-orientation` for shared CSS variants |
|
|
234
|
+
| `Chip` | `label` or default slot, `tone`, `removable`, `removeLabel`, `disabled`; emits `remove` |
|
|
235
|
+
| `DescriptionList` | `items: {term,description}[]`, `variant: stacked\|horizontal\|compact`; `item:index` slots receive `{item}` |
|
|
236
|
+
| `Stat` | `label`, string/number `value`, `locale`, `description`, `trend`; numeric values format with Intl |
|
|
237
|
+
| `Timeline` | `label`, `items: {id,title,description?,date?,dateLabel?,status?}[]`; named item-ID slots; machine-readable native time, optional current step |
|
|
238
|
+
| `Meter` | Required `label`, `value`; native `min`, `max`, `low`, `high`, `optimum` semantics |
|
|
239
|
+
| `AvatarGroup` | `label`, `items: {name,src?,initials?}[]`, `max`, `remainingLabel(count)` |
|
|
240
|
+
| `DataTable` | `caption`, `rows: Record<string,unknown>[]`, `columns: {key,label,sortable?,rowHeader?}[]`, `rowKey`, `locale`; `v-model:sort-key`, `v-model:sort-direction`, initial `defaultSortKey` / `defaultSortDirection`; `sortLabel(column,nextDirection)`; `cell:key` slots receive `{row,index}` |
|
|
241
|
+
| `ServiceCard` | `title`, `description`, `href`, `actionLabel`, `badge`, `metadata`; `icon`, default and `action` slots |
|
|
242
|
+
| `ServiceDetails` | `title`, `description`, DescriptionList `items`; default and `action` slots |
|
|
243
|
+
| `PortalHeader` | `brand`, `homeHref`, `links: {label,href,current?}[]`, `navLabel`; `logo`, `actions`, default slots Optional top-level `groups` contain a label and child links. See [grouped navigation](../../docs/nic-portal-navigation.md). |
|
|
244
|
+
| `PortalFooter` | `brand`, `copyright`, `links`, `navLabel`; default content slot |
|
|
245
|
+
| `Feedback` | `label`, selected answer string `v-model` (`yes`/`no`), `defaultValue`, `yesLabel`, `noLabel`, `commentLabel`, `submitLabel`, `thanks`, `disabled`, `readonly`; emits `submit({value,comment})` |
|
|
246
|
+
| `CookieConsent` | `v-model:open`, `defaultOpen=true`, `label`, required `description`, `acceptLabel`, `rejectLabel`, `preferencesLabel`; emits `accept`, `reject`, `preferences`; no hidden storage or third-party initialization |
|
|
247
|
+
| `NotificationList` | `label`, `items: {id,title,description?,date?,dateLabel?,read?,href?}[]`, `emptyMessage`, `readLabel(item)`, `dismissLabel(item)`; emits `read(id)`, `dismiss(id)`; named ID slots |
|
|
248
|
+
|
|
249
|
+
DataTable sorting is immutable, stable and localized. It remains a native table;
|
|
250
|
+
use the existing Table component for unrestricted table composition. Platform
|
|
251
|
+
patterns render content supplied by the application: no government seals, trust
|
|
252
|
+
verification, identity verification, analytics or backend service are implied.
|
|
253
|
+
Feedback emits data for the consuming application to persist; CookieConsent
|
|
254
|
+
emits decisions for the application to enforce and persist.
|
|
255
|
+
|
|
256
|
+
## Layout primitives
|
|
257
|
+
|
|
258
|
+
All layout primitives forward native HTML attributes and accept `as` (default
|
|
259
|
+
`div`, or `section` for Section). Shared `LayoutProps` includes:
|
|
260
|
+
|
|
261
|
+
- `gap` and `padding`: token numbers 0–16 or CSS length strings, optionally
|
|
262
|
+
responsive `{base,sm,md,lg,xl}` objects.
|
|
263
|
+
- `align: start|center|end|stretch|baseline`,
|
|
264
|
+
`justify: start|center|end|between|around|evenly`, and `wrap`.
|
|
265
|
+
- `columns`: a positive number or responsive object; `minItemWidth` opts into
|
|
266
|
+
adaptive auto-fit columns instead.
|
|
267
|
+
- `side: start|end`, `sidebarWidth`, `collapseAt: sm|md|lg`, `maxWidth`, `ratio`.
|
|
268
|
+
|
|
269
|
+
| Component | Composition |
|
|
270
|
+
| ------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
271
|
+
| `Container` | Constrained centered content, optional `maxWidth` |
|
|
272
|
+
| `Stack` | Vertical flex layout |
|
|
273
|
+
| `Inline` | Horizontal flex layout with optional wrapping |
|
|
274
|
+
| `Grid` | Responsive explicit or adaptive grid |
|
|
275
|
+
| `Columns` | Same grid contract with a column-composition semantic name |
|
|
276
|
+
| `Sidebar` | First child is sidebar, second child is main content; `side` changes visual placement, `collapseAt` controls stacking |
|
|
277
|
+
| `Center` | Centered flex content |
|
|
278
|
+
| `Spacer` | Flexible empty space; keep decorative |
|
|
279
|
+
| `AspectRatio` | Media frame with positive `ratio`, e.g. `16 / 9` |
|
|
280
|
+
| `Section` | Semantic section; name it with native `aria-label` or a heading |
|
|
281
|
+
| `AppShell` | Use `header`, `sidebar`, default main content and `footer` slots. The Arabic skip link focuses main. Set `mainId` to choose its target ID and `skipLabel` to localize the link. |
|
|
282
|
+
| `PageHeader` | `title`, `description`, heading `level=1`; `breadcrumb`, `actions`, default slots; outer element is always header |
|
|
283
|
+
|
|
284
|
+
```vue
|
|
285
|
+
<Container max-width="72rem">
|
|
286
|
+
<Stack :gap="{ base: 4, lg: 8 }">
|
|
287
|
+
<PageHeader title="خدماتك" description="اختر الخدمة المناسبة">
|
|
288
|
+
<template #actions><Button>طلب جديد</Button></template>
|
|
289
|
+
</PageHeader>
|
|
290
|
+
<Grid :columns="{ base: 1, md: 2, lg: 3 }" :gap="4">
|
|
291
|
+
<ServiceCard title="تجديد طلب" description="راجع التفاصيل ثم قدّم الطلب."
|
|
292
|
+
href="/services/renew" action-label="بدء الخدمة" />
|
|
293
|
+
<ServiceCard title="متابعة طلب" href="/requests" action-label="عرض الطلبات" />
|
|
294
|
+
</Grid>
|
|
295
|
+
</Stack>
|
|
296
|
+
</Container>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Breakpoints are CSS-only: sm 40rem, md 48rem, lg 64rem, xl 80rem. Server and
|
|
300
|
+
client emit identical custom properties through shared `layoutStyles`; no
|
|
301
|
+
viewport measurements or hydration-dependent layout branches are used.
|
|
302
|
+
|
|
303
|
+
Maps, rich text, charting, code editors, PDF viewers, CAPTCHA and payments are
|
|
304
|
+
integration boundaries. Mount the chosen provider in a named Section/Card or
|
|
305
|
+
AspectRatio with its own accessible fallback and documented data contract. Hawiyah
|
|
306
|
+
does not simulate these engines or handle provider credentials or transactions.
|
|
307
|
+
|
|
308
|
+
## Portal shell
|
|
309
|
+
|
|
310
|
+
[`PortalLayout`, `PortalHeader` and `SecondaryNav`](PORTAL.md) provide a complete
|
|
311
|
+
Arabic-default portal shell with responsive navigation, breadcrumbs and footer.
|
|
312
|
+
Run the Vue example with `?preview=portal` to use the native composed shell.
|
|
313
|
+
|
|
314
|
+
## NIC card composition
|
|
315
|
+
|
|
316
|
+
See [cards](../../docs/nic-cards.md) for source-mapped spacing, variants, whole-card links, disabled semantics and content classes. Native framework consumers include `?preview=nic`; vanilla uses the documented semantic HTML recipe.
|
|
317
|
+
|
|
318
|
+
See [NIC button variants](../../docs/nic-buttons.md) for all ten appearances,
|
|
319
|
+
interaction states, dark-surface use and density adaptations.
|
|
320
|
+
|
|
321
|
+
[Ready component examples](../../docs/ready-component-examples.md) cover all five
|
|
322
|
+
alert/notification tones, header/footer composition and guide-only navigation containment.
|
|
323
|
+
# Native choice read-only state
|
|
324
|
+
|
|
325
|
+
`Checkbox`, `Radio` and `Switch` accept `readOnly` (`read-only` in templates).
|
|
326
|
+
The control remains keyboard-focusable and submits its value, while pointer and
|
|
327
|
+
keyboard activation leave its value and radio peers unchanged. Disabled remains
|
|
328
|
+
a separate native state. See [NIC states](../../docs/nic-choices.md).
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
[Site verification](../../docs/site-verification.md) composes a native disclosure above the header with deployment-owned domain and certificate information. [Grouped portal footers](../../docs/nic-footer.md) add navigation groups, support actions, legal links and identity slots.
|
|
332
|
+
|
|
333
|
+
[Link and breadcrumb states](../../docs/nic-links.md) document neutral/standalone variants, disabled destinations, source contrast substitutions and native adapter APIs.
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
### Table presentation and empty results
|
|
337
|
+
|
|
338
|
+
`Table` and `DataTable` expose `variant="default|striped|bordered"`,
|
|
339
|
+
`size="sm|md|lg"` and `emptyMessage`. DGA cells have a 48px default minimum;
|
|
340
|
+
40px/56px alternate sizes and striped/bordered variants are Hawiyah extensions.
|
|
341
|
+
Captions name keyboard-focusable horizontal scroll containers; row-header
|
|
342
|
+
columns render native `th scope="row"`. Empty data spans the column count and
|
|
343
|
+
uses an Arabic message by default. Sorting does not mutate caller records.
|
|
344
|
+
React/Vue native `data-variant` and `data-size` attributes remain supported;
|
|
345
|
+
typed props take precedence. `wrapperProps` customizes the scroll container.
|
|
346
|
+
The default sort-action label is Arabic; pass `sortLabel` for another language.
|
|
347
|
+
See [table evidence and adaptations](../../docs/nic-tables.md).
|
|
348
|
+
|
|
349
|
+
Rating inputs select whole numbers; finite prefilled values are clamped to the normalized maximum and floored. Fractional averages belong in `RatingDisplay`. Nonfinite maxima fall back to 5 and nonfinite values to 0. Arabic labels and Latin digits are the defaults.
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
### Search suggestions
|
|
353
|
+
|
|
354
|
+
SearchField accepts local string suggestions and remains a free-text input.
|
|
355
|
+
With suggestions supplied it exposes an editable combobox/listbox, highlighted
|
|
356
|
+
matches and a polite result count. Arrow keys wrap through matches; Enter on an
|
|
357
|
+
active suggestion selects it and prevents form submission. Ordinary Enter with
|
|
358
|
+
no active suggestion emits `search` with a trimmed, nonempty query and keeps
|
|
359
|
+
native form submission available. Choose either the search callback or the
|
|
360
|
+
form's submit handler for the application request; wiring both duplicates it.
|
|
361
|
+
The optional icon search action is a non-submit button and uses the callback.
|
|
362
|
+
Arabic clear/search labels are defaults and can be localized.
|
|
363
|
+
|
|
364
|
+
Escape dismisses an open list before reaching an enclosing dialog; another
|
|
365
|
+
Escape can dismiss the dialog. Composition/modifier keys do not commit matches.
|
|
366
|
+
Readonly inputs remain searchable but cannot edit/clear/select suggestions;
|
|
367
|
+
disabled inputs cannot search. Blur, outside press, reset and changed suggestion
|
|
368
|
+
configuration clear active-option state. No remote search service is called.
|
|
369
|
+
|
|
370
|
+
### Content navigation
|
|
371
|
+
|
|
372
|
+
`ContentNavigation` follows application-owned section IDs using nested
|
|
373
|
+
`items: {id, label, disabled?, children?}[]`. Options are `label` (Arabic default),
|
|
374
|
+
`showHeading` (true), `sticky` (false), `scrollRoot` (null/window) and `offset`
|
|
375
|
+
(80px). `@current-change="onCurrentChange"` reports the current section ID. Ordinary
|
|
376
|
+
activation scrolls without changing the URL; keyboard activation also focuses
|
|
377
|
+
the target. Modified anchor clicks retain browser behavior. Disabled entries
|
|
378
|
+
remain noninteractive text links; no section content is created or hidden.
|
|
379
|
+
|
|
380
|
+
```vue
|
|
381
|
+
<script setup>
|
|
382
|
+
import {ContentNavigation} from '@hawiyah/vue';
|
|
383
|
+
const sections = [{id: 'requirements', label: 'المتطلبات'}];
|
|
384
|
+
</script>
|
|
385
|
+
<template>
|
|
386
|
+
<ContentNavigation :items="sections" />
|
|
387
|
+
<section id="requirements"><h2>المتطلبات</h2></section>
|
|
388
|
+
</template>
|
|
389
|
+
```
|