@7365admin1/layer-common 3.2.6 → 3.2.8-staging.200
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 +6 -0
- package/assets/css/primitives.css +1113 -0
- package/assets/css/screens.css +1097 -0
- package/assets/css/shell.css +258 -0
- package/assets/css/tokens.css +236 -0
- package/components/AcceptDialog.vue +17 -18
- package/components/AccessCard/AvailableStats.vue +24 -16
- package/components/AccessCardAddForm.vue +42 -42
- package/components/AccessCardAssignToUnitForm.vue +13 -21
- package/components/AccessCardDeleteDialog.vue +41 -39
- package/components/AccessCardDetailsDialog.vue +125 -79
- package/components/AccessCardPreviewDialog.vue +58 -84
- package/components/AccessCardQrTagging.vue +60 -63
- package/components/AccessCardReplaceForm.vue +27 -23
- package/components/AccessManagement.vue +86 -85
- package/components/AddEqupmentForm.vue +18 -22
- package/components/AddPassKeyToVisitor.vue +95 -73
- package/components/AppButton.vue +62 -0
- package/components/AppCard.vue +20 -0
- package/components/AppDateField.vue +49 -0
- package/components/AppField.vue +76 -0
- package/components/AppKpiTile.vue +65 -0
- package/components/AppSegmented.vue +38 -0
- package/components/AppSelect.vue +247 -0
- package/components/AreaChecklistHistoryLogs.vue +51 -44
- package/components/AreaChecklistHistoryMain.vue +14 -7
- package/components/AreaFormDialog.vue +71 -59
- package/components/AreaMain.vue +73 -107
- package/components/AttachmentsViewer.vue +84 -22
- package/components/AttendanceCheckInOutDialog.vue +85 -88
- package/components/AttendanceDetailsDialog.vue +57 -63
- package/components/AttendanceMain.vue +4 -3
- package/components/AttendanceMapSearchDialog.vue +42 -44
- package/components/AttendanceSettingsDialog.vue +79 -63
- package/components/Avatar/Main.vue +54 -2
- package/components/BillingMain.vue +26 -30
- package/components/BtnUploadFile.vue +53 -11
- package/components/BuildingForm.vue +34 -27
- package/components/BuildingManagement/buildings.vue +39 -39
- package/components/BuildingManagement/units.vue +26 -42
- package/components/BuildingUnitFormAdd.vue +20 -23
- package/components/BuildingUnitFormEdit.vue +8 -4
- package/components/BulletinBoardForm.vue +19 -24
- package/components/BulletinBoardManagement.vue +49 -57
- package/components/BulletinBoardView.vue +9 -6
- package/components/BulletinExpirationChip.vue +13 -4
- package/components/Button/Close.vue +2 -2
- package/components/CameraForm.vue +21 -22
- package/components/CameraMain.vue +50 -49
- package/components/Card/DeleteConfirmation.vue +24 -22
- package/components/Card/MemberInfoSummary.vue +28 -3
- package/components/Card/Toggle.vue +15 -3
- package/components/CardToolbar.vue +37 -0
- package/components/Carousel.vue +56 -36
- package/components/Chat/Bubbles.vue +43 -14
- package/components/Chat/Information.vue +49 -32
- package/components/Chat/ListCard.vue +38 -9
- package/components/Chat/Message.vue +41 -15
- package/components/Chat/Navigation.vue +27 -15
- package/components/Chat/SkeletonLoader.vue +9 -2
- package/components/ChecklistItemRow.vue +25 -1
- package/components/CleaningScheduleMain.vue +44 -49
- package/components/ClientDetailForm.vue +81 -56
- package/components/ClientMain.vue +92 -82
- package/components/ConfirmDialog.vue +14 -8
- package/components/Container/Standard.vue +9 -7
- package/components/CreateSubsciptionPlan.vue +148 -89
- package/components/DashboardEmptyState.vue +48 -3
- package/components/DashboardMain.vue +924 -676
- package/components/DashboardPanel.vue +84 -21
- package/components/DeliveryCompany.vue +34 -20
- package/components/Dialog/DeleteConfirmation.vue +20 -21
- package/components/Dialog/ReplaceAutofillPrompt.vue +19 -26
- package/components/Dialog/ReusablePrompt.vue +30 -29
- package/components/Dialog/UpdateMoreAction.vue +62 -59
- package/components/DocumentForm.vue +14 -21
- package/components/DocumentManagement.vue +162 -108
- package/components/DocumentViewer.vue +29 -12
- package/components/DrawImage.vue +29 -21
- package/components/EntryPass/QrTemplatePreview.vue +27 -16
- package/components/EntryPassInformation.vue +40 -10
- package/components/EntryPassMain.vue +49 -27
- package/components/EquipmentItemMain.vue +84 -97
- package/components/EquipmentManagementMain.vue +81 -103
- package/components/Facility/BookingSetup.vue +43 -52
- package/components/Feedback/Form.vue +26 -12
- package/components/FeedbackMain.vue +35 -49
- package/components/FileInput.vue +75 -58
- package/components/FileInputWithList.vue +59 -12
- package/components/FormDialog.vue +60 -21
- package/components/HidAccessLogDashboard.vue +512 -490
- package/components/HidCameraCaptureDialog.vue +216 -0
- package/components/HidEnabledGate.vue +67 -9
- package/components/HidIntercomManagement.vue +1322 -653
- package/components/HidQrCodeConfiguration.vue +1030 -258
- package/components/HidReaderForm.vue +142 -59
- package/components/HidReaderManagement.vue +211 -323
- package/components/HidServiceSettingsPanel.vue +44 -13
- package/components/HidUserEnrollment.vue +1185 -412
- package/components/HygieneUpdateMoreAction.vue +44 -44
- package/components/IncidentReport/Authorities.vue +30 -18
- package/components/IncidentReport/IncidentInformation.vue +10 -10
- package/components/IncidentReport/IncidentInformationDownload.vue +3 -4
- package/components/IncidentReport/affectedEntities.vue +41 -20
- package/components/Input/Date.vue +3 -0
- package/components/Input/DatePicker.vue +1 -2
- package/components/Input/DateTimePicker.vue +1 -1
- package/components/Input/File.vue +55 -10
- package/components/Input/FileV2.vue +39 -6
- package/components/Input/InputPhoneNumberV2.vue +2 -1
- package/components/Input/ListGroupSelection.vue +56 -8
- package/components/Input/NRICNumber.vue +1 -0
- package/components/Input/NewDate.vue +1 -0
- package/components/Input/Number.vue +1 -0
- package/components/Input/Password.vue +1 -0
- package/components/Input/PhoneNumber.vue +21 -1
- package/components/Input/VehicleNumber.vue +1 -0
- package/components/InputLabel.vue +2 -2
- package/components/InvitationClientForm.vue +21 -19
- package/components/InvitationForm.vue +15 -21
- package/components/InvitationMain.vue +46 -61
- package/components/Layout/Header.vue +263 -36
- package/components/Layout/NavigationDrawer.vue +300 -30
- package/components/ListItem.vue +33 -3
- package/components/LocalPagination.vue +27 -3
- package/components/ManageChecklistMain.vue +136 -86
- package/components/MemberInformation.vue +32 -16
- package/components/MemberMain.vue +113 -93
- package/components/MyAttendanceMain.vue +3 -5
- package/components/NavigationItem.vue +83 -3
- package/components/Nfc/NFCPatrolReportMain.vue +47 -33
- package/components/Nfc/NFCPatrolRouteForm.vue +18 -20
- package/components/Nfc/NFCPatrolRouteMain.vue +116 -103
- package/components/Nfc/NFCPatrolSettings.vue +14 -4
- package/components/Nfc/NFCTagForm.vue +22 -8
- package/components/Nfc/NFCTagMain.vue +41 -43
- package/components/Nfc/PatrolReport/DailyReportTab.vue +8 -1
- package/components/Nfc/PatrolReport/MonthlyReportTab.vue +8 -1
- package/components/Nfc/PatrolReport/MonthlyReportTable.vue +5 -3
- package/components/Nfc/PatrolReport/PatrolActivityTable.vue +26 -6
- package/components/Nfc/PatrolReport/PatrolReportTab.vue +8 -0
- package/components/Nfc/PatrolReport/PatrolRouteSummary.vue +41 -9
- package/components/Nfc/PatrolReport/RemarksDialog.vue +39 -9
- package/components/Nfc/PatrolReport/ReportEmptyState.vue +29 -9
- package/components/Nfc/PatrolReport/ReportFilters.vue +19 -10
- package/components/Nfc/PatrolReport/ReportLocationHeader.vue +32 -6
- package/components/Nfc/PatrolReport/SummaryReportTable.vue +28 -6
- package/components/NotificationSettings.vue +373 -0
- package/components/NumberSettingField.vue +9 -2
- package/components/OnlineFormConfigurationForm.vue +725 -237
- package/components/OnlineFormFill.vue +213 -106
- package/components/OnlineFormRenderPreview.vue +25 -30
- package/components/OnlineFormsConfiguration.vue +113 -109
- package/components/OrgViewDialog.vue +34 -16
- package/components/OvernightParkingAvailability.vue +49 -26
- package/components/OvernightParkingManagement.vue +78 -18
- package/components/PageHeader.vue +43 -0
- package/components/PassInformation.vue +109 -53
- package/components/PasswordConfirmation.vue +44 -26
- package/components/PeopleForm.vue +41 -20
- package/components/PhotoUpload.vue +110 -48
- package/components/PlaceholderComponent.vue +35 -19
- package/components/PlanActionsMenu.vue +12 -2
- package/components/PlanStatusBadge.vue +7 -8
- package/components/PlateNumberDisplay.vue +9 -6
- package/components/QrTemplate/PrintDialog.vue +66 -43
- package/components/RolePermissionFormCreate.vue +104 -79
- package/components/RolePermissionFormPreviewUpdate.vue +111 -109
- package/components/RolePermissionMain.vue +183 -81
- package/components/ScanVisitorQRCode.vue +99 -35
- package/components/ScheduleAreaMain.vue +34 -59
- package/components/ScheduleTaskForm.vue +61 -42
- package/components/ScheduleTaskMain.vue +56 -69
- package/components/SearchVehicleNumberUser.vue +39 -37
- package/components/ServiceProviderFormCreate.vue +29 -20
- package/components/ServiceProviderInvitationPrompt.vue +155 -0
- package/components/ServiceProviderMain.vue +601 -432
- package/components/Signature.vue +40 -34
- package/components/SignaturePad.vue +5 -29
- package/components/SiteSettings.vue +41 -11
- package/components/SiteSettingsWorkOrder.vue +61 -30
- package/components/SlideCardGroup.vue +35 -11
- package/components/Snackbar.vue +36 -3
- package/components/SpecificAttr.vue +18 -8
- package/components/StatusChip.vue +156 -0
- package/components/StockCard.vue +17 -12
- package/components/SubscriptionPlanTable.vue +207 -140
- package/components/SwitchContext.vue +201 -9
- package/components/TableHygiene.vue +36 -46
- package/components/TableList.vue +10 -10
- package/components/TableListSecondary.vue +105 -54
- package/components/TableMain.vue +241 -79
- package/components/TableV3.vue +61 -70
- package/components/TiptapEditor.vue +33 -40
- package/components/TiptapEditorQr.vue +5 -2
- package/components/Tooltip/Info.vue +69 -24
- package/components/UnitMain.vue +40 -60
- package/components/UnitPersonCard.vue +42 -13
- package/components/VehicleAddSelection.vue +48 -32
- package/components/VehicleForm.vue +112 -129
- package/components/VehicleManagement.vue +26 -12
- package/components/VehicleUpdateMoreAction.vue +59 -46
- package/components/VisitorDataFromScannedQRCodeForm.vue +90 -65
- package/components/VisitorForm.vue +774 -210
- package/components/VisitorFormSelection.vue +40 -37
- package/components/VisitorManagement.vue +239 -82
- package/components/VisitorPassKeyQRScanner.vue +65 -18
- package/components/VisitorSearchResultSummary.vue +60 -16
- package/components/VisitorSocketPopUp.vue +22 -14
- package/components/VisitorsReportPreview.vue +44 -29
- package/components/WorkOrder/Create.vue +26 -17
- package/components/WorkOrder/ListView.vue +38 -7
- package/components/WorkOrder/Main.vue +62 -59
- package/composables/useFeedback.ts +3 -3
- package/composables/useHidAmico.ts +269 -0
- package/composables/useHidNavigation.ts +2 -9
- package/composables/useMember.ts +3 -3
- package/composables/useNFCPatrolDailyReport.ts +13 -0
- package/composables/useNFCPatrolMonthlyReport.ts +22 -56
- package/composables/useNFCPatrolReport.ts +13 -0
- package/composables/useNotificationPreference.ts +87 -0
- package/composables/useOnlineFormPages.ts +2 -0
- package/composables/useRole.ts +22 -0
- package/composables/useServiceProvider.ts +3 -3
- package/composables/useServiceProviderInvitation.ts +145 -0
- package/composables/useSipWebPhone.ts +336 -0
- package/composables/useSubscriptionPlan.ts +62 -0
- package/composables/useThemePreference.ts +63 -0
- package/composables/useVisitor.ts +6 -1
- package/composables/useWebUsb.ts +127 -37
- package/composables/useWorkOrder.ts +17 -3
- package/error.vue +30 -6
- package/nuxt.config.ts +36 -0
- package/package.json +25 -4
- package/pages/[org]/[site]/access-mgmt/administrator/index.vue +2 -2
- package/pages/[org]/[site]/access-mgmt/{identity-mapping → hid-cards}/index.vue +2 -2
- package/pages/[org]/[site]/access-mgmt/intercom/index.vue +1 -1
- package/pages/notification-settings.vue +19 -0
- package/pages/payment-method-linked.vue +34 -10
- package/pages/require-customer.vue +48 -10
- package/pages/require-organization-membership.vue +32 -8
- package/pages/unauthorized.vue +29 -4
- package/plugins/secure-member.client.ts +21 -56
- package/plugins/vuetify.ts +69 -2
- package/types/nfc-patrol-report.ts +3 -2
- package/types/site.d.ts +71 -0
- package/types/subscription.ts +18 -11
- package/utils/breadcrumb.test.ts +108 -0
- package/utils/breadcrumb.ts +82 -0
- package/utils/dashboard.test.ts +118 -0
- package/utils/dashboard.ts +53 -0
- package/utils/data.test.ts +95 -0
- package/utils/data.ts +40 -2
- package/utils/hid-discover.test.ts +102 -0
- package/utils/list-page.test.ts +60 -0
- package/utils/list-page.ts +38 -0
- package/utils/materialSymbols.ts +363 -0
- package/utils/nav-sections.test.ts +190 -0
- package/utils/nav-sections.ts +151 -0
- package/utils/nfc-patrol-report.test.ts +130 -0
- package/utils/nfc-patrol-report.ts +101 -0
- package/utils/role.test.ts +69 -0
- package/utils/role.ts +10 -0
- package/utils/route-name.test.ts +85 -0
- package/utils/route-name.ts +24 -0
- package/utils/status.test.ts +110 -0
- package/utils/status.ts +135 -0
- package/utils/table-card.test.ts +84 -0
- package/utils/theme-aa-ledger.ts +148 -0
- package/utils/theme.test.ts +485 -7
- package/utils/theme.ts +295 -110
- package/.changeset/README.md +0 -8
- package/.changeset/config.json +0 -11
- package/.editorconfig +0 -12
- package/.github/workflows/main.yml +0 -17
- package/.github/workflows/publish-staging.yml +0 -47
- package/.github/workflows/publish.yml +0 -39
- package/PUBLISHING.md +0 -269
- package/components/HidIdentityMapping.vue +0 -975
- package/components/ScheduleTaskAreaFormDialog.vue +0 -144
- package/components/ScheduleTaskAreaUpdateMoreAction.vue +0 -109
- package/components/ScheduleTastTicketMain.vue +0 -182
- package/components/TableWithButton.vue +0 -94
- package/test/visitor-socket.test.mjs +0 -36
package/utils/theme.ts
CHANGED
|
@@ -1,136 +1,321 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* THE
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* `
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
2
|
+
* THE PLATFORM PALETTE, AND THE BRIDGE BETWEEN TWO COLOUR SYSTEMS.
|
|
3
|
+
*
|
|
4
|
+
* The redesign is specified in raw CSS custom properties (`--bg`, `--card`,
|
|
5
|
+
* `--muted`, `--ok`...). This product is built in Vuetify, which paints from
|
|
6
|
+
* its own `--v-theme-*` RGB triples. Stacking the two would leave every
|
|
7
|
+
* `v-card`, `v-btn`, `v-chip` and `v-data-table` in eleven applications on its
|
|
8
|
+
* factory colours underneath a correct-looking token file.
|
|
9
|
+
*
|
|
10
|
+
* So there is ONE source of truth - `PALETTE` below - and it flows one way:
|
|
11
|
+
*
|
|
12
|
+
* PALETTE -> Vuetify theme colours -> `--v-theme-*` -> `--bg` etc.
|
|
13
|
+
* (LIGHT_THEME/DARK_THEME) (Vuetify emits) (assets/css/tokens.css)
|
|
14
|
+
*
|
|
15
|
+
* `assets/css/tokens.css` does not restate a single colour; it aliases each
|
|
16
|
+
* design token to the Vuetify variable that already holds it. That matters for
|
|
17
|
+
* more than tidiness: Vuetify puts `.v-theme--light` / `.v-theme--dark` on
|
|
18
|
+
* every `v-theme-provider` subtree, so a token read inside the `plain-dark`
|
|
19
|
+
* layout or inside `FormDialog` resolves to that subtree's theme instead of the
|
|
20
|
+
* page's. A `body.dark` class - which is how the prototype does it - cannot do
|
|
21
|
+
* that, and would have gone wrong in exactly those two places.
|
|
22
|
+
*
|
|
23
|
+
* Every ratio quoted here is WCAG 2.1, alpha composited against the surface the
|
|
24
|
+
* value actually sits on, and `utils/theme.test.ts` re-measures all of them on
|
|
25
|
+
* every run. This file has already been got wrong once by moving a colour for
|
|
26
|
+
* one use and forgetting the other.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* THE SIX LIGHT VALUES ARE BACK ON THE DESIGN - the owner's decision,
|
|
31
|
+
* 2026-08-14, which REVERSES the 2026-08-13 one recorded below.
|
|
32
|
+
*
|
|
33
|
+
* 2026-08-13 was "minimal darkening, keep the look": the light theme failed AA
|
|
34
|
+
* on 27 text pairs as handed over, so six values were darkened just enough to
|
|
35
|
+
* clear 4.5:1. 2026-08-14 is "100% design fidelity over WCAG AA" - the darker
|
|
36
|
+
* `--muted` in particular flattened the hierarchy the design is built on, and
|
|
37
|
+
* that was visible on staging. All six go back to the handoff, exactly:
|
|
38
|
+
*
|
|
39
|
+
* --muted #6b7079 -> #8b8f98
|
|
40
|
+
* --ok #0e7c58 -> #0f8a62
|
|
41
|
+
* --warn #8e6611 -> #a97a14
|
|
42
|
+
* --err #bc4444 -> #cf4b4b
|
|
43
|
+
* --info #3869c9 -> #3b6fd4
|
|
44
|
+
* --accent-text #476aaf -> #4a6eb6
|
|
45
|
+
*
|
|
46
|
+
* WHAT THAT KNOWINGLY COSTS: 16 of the 22 light pairs a person reads are now
|
|
47
|
+
* below AA. `utils/theme-aa-ledger.ts` is the full list with measured ratios and
|
|
48
|
+
* `theme.test.ts` pins every one of them, so the failures are recorded rather
|
|
49
|
+
* than hidden and any later drift - in either direction - still fails the build.
|
|
50
|
+
* The worst, measured (WCAG 2.1, alpha composited):
|
|
51
|
+
*
|
|
52
|
+
* --muted on the page bg 2.99:1 (needs 4.5)
|
|
53
|
+
* --muted on a table header band 3.10:1
|
|
54
|
+
* --muted on the sidebar 3.13:1
|
|
55
|
+
* --muted on a card 3.24:1 - every table header, breadcrumb,
|
|
56
|
+
* KPI sub-line and empty state
|
|
57
|
+
* --warn on its Pending chip 3.38:1
|
|
58
|
+
* --ok on its chip 3.82:1
|
|
59
|
+
* --warn / white on warn fill 3.83:1
|
|
60
|
+
* --err on its chip 3.86:1
|
|
61
|
+
*
|
|
62
|
+
* Six light pairs still pass: text, text2, info as text, white on the info fill,
|
|
63
|
+
* accent-text as a link, and white on primary-button.
|
|
64
|
+
*
|
|
65
|
+
* The DARK theme was exact as handed over and still is, and its AA assertions
|
|
66
|
+
* are untouched - dark mode remains fully compliant.
|
|
67
|
+
*
|
|
68
|
+
* `--accent-strong` (#4b74c4) is NOT one of the six and does not move. It is an
|
|
69
|
+
* addition, not a darkening: the design puts white on `--accent` at 3.23:1, and
|
|
70
|
+
* `--accent` itself is still the design's exact colour everywhere it is a line,
|
|
71
|
+
* a fill edge or a soft background. See the note below.
|
|
72
|
+
*
|
|
73
|
+
* The soft chip BACKGROUNDS are, and always were, exactly as designed.
|
|
74
|
+
*
|
|
75
|
+
* `--accent-text` is `color-mix(in oklab, var(--accent) 75%, var(--text))` in
|
|
76
|
+
* the design. It is resolved to a plain hex here because Vuetify needs a
|
|
77
|
+
* concrete colour and because a test cannot measure a `color-mix()`; the hex
|
|
78
|
+
* below is that mix resolved in a browser, not an approximation.
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* WHITE ON THE ACCENT: A DARKER ACCENT FOR FILLS, NOT A BIGGER FONT.
|
|
83
|
+
*
|
|
84
|
+
* White on `--accent` (#5b8def) is 3.23:1 in BOTH themes - the fill is
|
|
85
|
+
* theme-independent, so the failure is too. It is the primary button's label
|
|
86
|
+
* and the active segment of the Today/Week/Month control. There were two ways
|
|
87
|
+
* out and only one of them keeps the design:
|
|
88
|
+
*
|
|
89
|
+
* - The type route. 3.23:1 is legal for LARGE text, which starts at 18.66px
|
|
90
|
+
* bold. The design's buttons are 13.5px/700-800 in a 40px pill. Reaching
|
|
91
|
+
* 18.66px would make the label taller than the button was drawn for and
|
|
92
|
+
* change every button in the product. Rejected.
|
|
93
|
+
* - `--accent-strong`, an 18%-darker accent used ONLY where a white label
|
|
94
|
+
* sits on an accent fill. White reads 4.57:1 on it, and the fill still
|
|
95
|
+
* holds its own edge (4.57:1 against a light card, 3.64:1 against a dark
|
|
96
|
+
* one). Chosen.
|
|
97
|
+
*
|
|
98
|
+
* The point is what it does NOT touch. `--accent` itself is unchanged, so the
|
|
99
|
+
* links, the active sidebar item, the tab underline, the toggle in its on
|
|
100
|
+
* state, the chart lines, the focus rings, the logo tile and every
|
|
101
|
+
* `--accent-soft` background are the exact colour the design specifies. Only
|
|
102
|
+
* the two filled surfaces that carry white lettering are darker.
|
|
21
103
|
*/
|
|
22
104
|
|
|
23
105
|
/**
|
|
24
106
|
* `primary` IS BOTH A FILL AND A FOREGROUND, AND ONE VALUE CANNOT SERVE BOTH.
|
|
25
107
|
*
|
|
26
108
|
* Vuetify emits `.bg-primary` and `.text-primary` from the same token, so the
|
|
27
|
-
* colour that fills
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
109
|
+
* colour that fills a button is also the colour of every `class="text-primary"`
|
|
110
|
+
* sentence, every `color="primary"` icon, spinner and text button, and the
|
|
111
|
+
* focused outline on every input. On a dark page those pull in opposite
|
|
112
|
+
* directions: a fill that carries a white label wants to be dark, a foreground
|
|
113
|
+
* that is readable on a dark card wants to be light. There is no overlap.
|
|
114
|
+
*
|
|
115
|
+
* That is why the split established on 2026-08-12 survives this rewrite, just
|
|
116
|
+
* pointed at the new palette:
|
|
117
|
+
*
|
|
118
|
+
* primary = --accent-text (a FOREGROUND: links, icons, text)
|
|
119
|
+
* primary-button = --accent-strong (a FILL that carries a white label)
|
|
120
|
+
* brand-surface = --sidebar (the navigation drawer's own fill)
|
|
121
|
+
*
|
|
122
|
+
* Re-pointing rather than renaming is deliberate: `text-primary` and
|
|
123
|
+
* `primary-button` are written in roughly eighty places across this layer and
|
|
124
|
+
* the applications, and none of them has to change.
|
|
39
125
|
*/
|
|
40
126
|
|
|
41
127
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* light page, the same `surface` the app bar and the cards use on the dark
|
|
52
|
-
* page - so the drawer reads as part of the application it is in and the
|
|
53
|
-
* switch visibly changes it. The brand is carried by the title and by the
|
|
54
|
-
* active item, which is `primary` in both themes, rather than by painting the
|
|
55
|
-
* whole rail.
|
|
56
|
-
*
|
|
57
|
-
* The drawer is a low-contrast panel against the page by design (1.13:1 light,
|
|
58
|
-
* 1.19:1 dark, exactly like every other surface in Material), so its edge is
|
|
59
|
-
* what carries the boundary. `NavigationDrawer.vue` raises `border-opacity` on
|
|
60
|
-
* itself alone to reach 3:1 there without redrawing every table and card edge
|
|
61
|
-
* in eleven applications.
|
|
62
|
-
*
|
|
63
|
-
* `on-brand-surface` is set explicitly rather than left to Vuetify's black or
|
|
64
|
-
* white, so the label is the same near-black / near-white the rest of the
|
|
65
|
-
* theme reads in.
|
|
128
|
+
* VUETIFY DERIVES THE LABEL ON A FILLED COLOUR, AND ITS GUESS IS WHITE.
|
|
129
|
+
*
|
|
130
|
+
* Measured in a browser, not assumed: given `warning`, `info`, `error`,
|
|
131
|
+
* `success` or `primary` as a fill, Vuetify picks a WHITE foreground. On this
|
|
132
|
+
* palette's dark theme that is 2.04:1 to 2.99:1 - every filled chip, alert,
|
|
133
|
+
* badge and button in dark mode. So each `on-*` is set explicitly below rather
|
|
134
|
+
* than left to the derivation. Light's fills are dark enough that white is in
|
|
135
|
+
* fact right, and it is still written down there, so that no component in
|
|
136
|
+
* eleven applications is left depending on Vuetify guessing correctly.
|
|
66
137
|
*/
|
|
67
|
-
export const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
138
|
+
export const PALETTE = {
|
|
139
|
+
light: {
|
|
140
|
+
/** Page background. */
|
|
141
|
+
bg: "#f6f6f2",
|
|
142
|
+
/** The navigation rail. */
|
|
143
|
+
sidebar: "#fbfbf8",
|
|
144
|
+
/** Cards, tables, modals, menus. */
|
|
145
|
+
card: "#ffffff",
|
|
146
|
+
/** Card and table edges. As designed - see the note in the test. */
|
|
147
|
+
border: "#e8e8e1",
|
|
148
|
+
/** Primary text. 17.24:1 on a card. */
|
|
149
|
+
text: "#191b1f",
|
|
150
|
+
/** Secondary text. 9.62:1 on a card. */
|
|
151
|
+
text2: "#41454d",
|
|
152
|
+
/** Table headers, breadcrumbs, KPI sub-lines. The design's. 3.24:1 on a card - below AA, knowingly. */
|
|
153
|
+
muted: "#8b8f98",
|
|
154
|
+
/** Completed / Paid / Available / Open. The design's. 3.82:1 on its chip - below AA, knowingly. */
|
|
155
|
+
ok: "#0e7c58",
|
|
156
|
+
/** Pending. The design's. 3.38:1 on its chip - below AA, knowingly. */
|
|
157
|
+
warn: "#8e6611",
|
|
158
|
+
/** In Use / Closed / Checkout. The design's. 3.86:1 on its chip - below AA, knowingly. */
|
|
159
|
+
err: "#bc4444",
|
|
160
|
+
/** Role and info tags. The design's. 4.20:1 on its chip - below AA, knowingly. */
|
|
161
|
+
info: "#3b6fd4",
|
|
162
|
+
/** The brand accent, exactly as designed. Never carries white lettering. */
|
|
163
|
+
accent: "#5b8def",
|
|
164
|
+
/** The only place the accent is darkened: fills with a white label. 4.57:1. */
|
|
165
|
+
accentStrong: "#4b74c4",
|
|
166
|
+
/** Links, active nav item, active tab. The design's oklab mix, resolved. 4.29:1 on `--accent-soft` over the sidebar - below AA, knowingly. */
|
|
167
|
+
accentText: "#4a6eb6",
|
|
168
|
+
/** Labels on the filled colours above. Light's fills carry white. */
|
|
169
|
+
onFill: "#ffffff",
|
|
170
|
+
},
|
|
171
|
+
dark: {
|
|
172
|
+
bg: "#131418",
|
|
173
|
+
sidebar: "#17181d",
|
|
174
|
+
card: "#1c1e24",
|
|
175
|
+
border: "#2a2d35",
|
|
176
|
+
text: "#eef0f3",
|
|
177
|
+
text2: "#c6cad2",
|
|
178
|
+
/** Passes as designed at 4.93:1 - the dark theme needed no darkening. */
|
|
179
|
+
muted: "#868c98",
|
|
180
|
+
ok: "#41c795",
|
|
181
|
+
warn: "#dcaf4e",
|
|
182
|
+
err: "#e57373",
|
|
183
|
+
info: "#7da6ec",
|
|
184
|
+
accent: "#5b8def",
|
|
185
|
+
/** Same value as light: the failure was theme-independent, so the fix is. */
|
|
186
|
+
accentStrong: "#4b74c4",
|
|
187
|
+
accentText: "#78a2f4",
|
|
71
188
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
189
|
+
* Dark's fills are LIGHT colours, so their label is the page ink, not
|
|
190
|
+
* white. White on them measures 2.04:1 to 2.99:1; this reads 6.16:1 to
|
|
191
|
+
* 9.01:1. Not a new colour - it is `bg` above, so a filled chip reads as a
|
|
192
|
+
* hole punched in the page.
|
|
74
193
|
*/
|
|
75
|
-
|
|
76
|
-
/** The drawer's label colour. On the rail: 15.43:1. */
|
|
77
|
-
"on-brand-surface": "#0B1B27",
|
|
78
|
-
"primary-button": "#1867C0",
|
|
79
|
-
"text-primary": "#052439",
|
|
80
|
-
},
|
|
81
|
-
variables: {
|
|
82
|
-
"disabled-opacity": 0.55,
|
|
83
|
-
"border-opacity": 0.26,
|
|
194
|
+
onFill: "#131418",
|
|
84
195
|
},
|
|
85
|
-
};
|
|
196
|
+
} as const;
|
|
86
197
|
|
|
87
198
|
/**
|
|
88
|
-
*
|
|
199
|
+
* The values are widened back to `string`. `PALETTE` is `as const` so a test
|
|
200
|
+
* can assert an exact hex, but the builder below takes EITHER theme - and with
|
|
201
|
+
* the literal types intact, "#131418" is not assignable to "#f6f6f2" and the
|
|
202
|
+
* dark theme will not compile.
|
|
89
203
|
*/
|
|
90
|
-
export
|
|
91
|
-
|
|
204
|
+
export type TPalette = { readonly [K in keyof (typeof PALETTE)["light"]]: string };
|
|
205
|
+
|
|
206
|
+
type Palette = TPalette;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* One theme builder for both themes, so a colour can never be wired into light
|
|
210
|
+
* and forgotten in dark - which is the specific way this file broke before.
|
|
211
|
+
*/
|
|
212
|
+
const theme = (dark: boolean, p: Palette) => ({
|
|
213
|
+
dark,
|
|
92
214
|
colors: {
|
|
215
|
+
// --- the design's surfaces -------------------------------------------
|
|
216
|
+
background: p.bg,
|
|
217
|
+
surface: p.card,
|
|
218
|
+
"on-background": p.text,
|
|
219
|
+
"on-surface": p.text,
|
|
220
|
+
/** Menus and raised sheets sit on the card colour, not Vuetify's grey. */
|
|
221
|
+
"surface-bright": p.card,
|
|
222
|
+
"surface-light": p.card,
|
|
223
|
+
"surface-variant": p.sidebar,
|
|
224
|
+
"on-surface-variant": p.text2,
|
|
225
|
+
|
|
226
|
+
// --- the split accent -------------------------------------------------
|
|
227
|
+
/** A FOREGROUND. See the note above before making this a fill colour. */
|
|
228
|
+
primary: p.accentText,
|
|
229
|
+
"on-primary": p.onFill,
|
|
230
|
+
/** The FILL that carries a white label. White on it: 4.57:1, both themes. */
|
|
231
|
+
"primary-button": p.accentStrong,
|
|
232
|
+
"on-primary-button": "#ffffff",
|
|
233
|
+
/** The navigation drawer's fill = the design's sidebar colour. */
|
|
234
|
+
"brand-surface": p.sidebar,
|
|
235
|
+
"on-brand-surface": p.text,
|
|
236
|
+
/** ~80 call sites across the layer and the apps. Now the design's ink. */
|
|
237
|
+
"text-primary": p.text,
|
|
238
|
+
|
|
239
|
+
// --- semantic status, mapped as the design specifies ------------------
|
|
240
|
+
/** Completed / Paid / Available / Open. */
|
|
241
|
+
success: p.ok,
|
|
242
|
+
"on-success": p.onFill,
|
|
243
|
+
/** Pending. */
|
|
244
|
+
warning: p.warn,
|
|
245
|
+
"on-warning": p.onFill,
|
|
246
|
+
/** In Use / Closed / Checkout. */
|
|
247
|
+
error: p.err,
|
|
248
|
+
"on-error": p.onFill,
|
|
249
|
+
/** Role and info tags. */
|
|
250
|
+
info: p.info,
|
|
251
|
+
"on-info": p.onFill,
|
|
252
|
+
|
|
253
|
+
// --- design tokens with no Vuetify equivalent -------------------------
|
|
254
|
+
// These exist so `assets/css/tokens.css` can alias `--text2`, `--muted`,
|
|
255
|
+
// `--border`, `--accent` and friends to a `--v-theme-*` that Vuetify keeps
|
|
256
|
+
// in step with the active theme, rather than restating hexes in CSS.
|
|
257
|
+
accent: p.accent,
|
|
258
|
+
"accent-strong": p.accentStrong,
|
|
259
|
+
"accent-text": p.accentText,
|
|
260
|
+
text2: p.text2,
|
|
261
|
+
muted: p.muted,
|
|
262
|
+
border: p.border,
|
|
263
|
+
sidebar: p.sidebar,
|
|
264
|
+
},
|
|
265
|
+
variables: {
|
|
93
266
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
267
|
+
* AN OPACITY IS ONLY AS DARK AS THE INK IT IS APPLIED TO.
|
|
268
|
+
*
|
|
269
|
+
* Both values below were tuned when `on-surface` was Vuetify's pure black.
|
|
270
|
+
* The design's ink is `#191b1f`, which is lighter, so the SAME opacity now
|
|
271
|
+
* composites to a paler grey - and it showed up the moment the two screens
|
|
272
|
+
* that shipped today were re-rendered: every `text-medium-emphasis` line
|
|
273
|
+
* fell from 5.74:1 to 4.53:1 on a card and 4.41:1 on the page, taking the
|
|
274
|
+
* dashboard's site name and the preference screen's summary below AA.
|
|
275
|
+
*
|
|
276
|
+
* That is one cause with about two hundred call sites across eleven
|
|
277
|
+
* applications, so it is fixed once, here, rather than in the two places
|
|
278
|
+
* the measurement happened to catch.
|
|
279
|
+
*
|
|
280
|
+
* `medium-emphasis-opacity` 0.64: 5.11:1 on a card, 4.94:1 on the page,
|
|
281
|
+
* 5.04:1 on the sidebar. The minimum that clears AA is 0.61 and this keeps
|
|
282
|
+
* a margin, while staying clearly lighter than `--text2`'s 9.62:1 - it is
|
|
283
|
+
* still medium emphasis, not body text.
|
|
284
|
+
*
|
|
285
|
+
* `disabled-opacity` 0.62: the value that composites `#191b1f` to the same
|
|
286
|
+
* grey `#000000` reached at 0.55, so a disabled field is exactly as dark as
|
|
287
|
+
* it was before this palette. It is NOT 4.5:1 as rendered - Vuetify
|
|
288
|
+
* multiplies its own field alpha on top and the result measures 1.9:1 -
|
|
289
|
+
* but that compounding predates this work and un-compounding it means
|
|
290
|
+
* changing how an input draws, which is Phase 3's job, not a token's.
|
|
291
|
+
*
|
|
292
|
+
* The same number in both themes on purpose: a value that drifts apart
|
|
293
|
+
* between light and dark is a bug nobody sees until they flip the switch.
|
|
99
294
|
*/
|
|
100
|
-
background: "#0E1319",
|
|
101
|
-
surface: "#1B242F",
|
|
102
|
-
/** Stock dark ships a lavender #ccbfd6 here, which is not our product. */
|
|
103
|
-
"surface-bright": "#26313E",
|
|
104
|
-
"surface-light": "#26313E",
|
|
105
295
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
296
|
+
* `high-emphasis-opacity` 1, and this one REMOVES a dimming layer rather
|
|
297
|
+
* than retuning it. Vuetify's 0.87 exists to soften pure black into body
|
|
298
|
+
* ink; the design already ships body ink, so applying 0.87 on top of
|
|
299
|
+
* `#191b1f` dims text that was never black to begin with.
|
|
110
300
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* that
|
|
301
|
+
* It also compounds. A field label is high emphasis AND medium emphasis -
|
|
302
|
+
* 0.87 x 0.64 - which is how "Search work orders" was rendering at 3.95:1
|
|
303
|
+
* while every token it is built from passed on its own. Taking this to 1
|
|
304
|
+
* leaves one opacity on that label instead of two, and it measures 5.02:1.
|
|
115
305
|
*/
|
|
116
|
-
|
|
306
|
+
"high-emphasis-opacity": 1,
|
|
307
|
+
"medium-emphasis-opacity": 0.64,
|
|
308
|
+
"disabled-opacity": 0.62,
|
|
117
309
|
/**
|
|
118
|
-
*
|
|
119
|
-
* `
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* separate from `surface` so the drawer can be moved on its own later.
|
|
310
|
+
* Vuetify draws borders as `on-surface` at this opacity. The design's
|
|
311
|
+
* `--border` is a much softer edge than Material's default; these are the
|
|
312
|
+
* opacities that land closest to it while staying visible. Components that
|
|
313
|
+
* need a real boundary raise it on themselves - see `NavigationDrawer.vue`.
|
|
123
314
|
*/
|
|
124
|
-
"
|
|
125
|
-
/** The drawer's label colour. On the rail: 13.21:1. */
|
|
126
|
-
"on-brand-surface": "#E8ECF1",
|
|
127
|
-
/** Unchanged on purpose: it already passes in both themes. */
|
|
128
|
-
"primary-button": "#1867C0",
|
|
129
|
-
/** #052439 on a dark page measures 1.18:1. This is 15.72:1. */
|
|
130
|
-
"text-primary": "#E8ECF1",
|
|
131
|
-
},
|
|
132
|
-
variables: {
|
|
133
|
-
"disabled-opacity": 0.55,
|
|
134
|
-
"border-opacity": 0.35,
|
|
315
|
+
"border-opacity": dark ? 0.35 : 0.26,
|
|
135
316
|
},
|
|
136
|
-
};
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
export const LIGHT_THEME = theme(false, PALETTE.light);
|
|
320
|
+
|
|
321
|
+
export const DARK_THEME = theme(true, PALETTE.dark);
|
package/.changeset/README.md
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
# Changesets
|
|
2
|
-
|
|
3
|
-
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
-
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
-
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
-
|
|
7
|
-
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
-
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
package/.changeset/config.json
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json",
|
|
3
|
-
"changelog": "@changesets/cli/changelog",
|
|
4
|
-
"commit": false,
|
|
5
|
-
"fixed": [],
|
|
6
|
-
"linked": [],
|
|
7
|
-
"access": "public",
|
|
8
|
-
"baseBranch": "main",
|
|
9
|
-
"updateInternalDependencies": "patch",
|
|
10
|
-
"ignore": []
|
|
11
|
-
}
|
package/.editorconfig
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- "**"
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
build:
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
steps:
|
|
11
|
-
- uses: actions/checkout@v4
|
|
12
|
-
- uses: actions/setup-node@v4
|
|
13
|
-
with:
|
|
14
|
-
node-version: 20.x
|
|
15
|
-
cache: "yarn"
|
|
16
|
-
- run: yarn install --frozen-lockfile && yarn dev:prepare
|
|
17
|
-
- run: yarn build
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
name: Publish Staging
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- staging
|
|
6
|
-
|
|
7
|
-
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
publish:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v4
|
|
14
|
-
|
|
15
|
-
- uses: actions/setup-node@v4
|
|
16
|
-
with:
|
|
17
|
-
node-version: 20.x
|
|
18
|
-
cache: "yarn"
|
|
19
|
-
cache-dependency-path: yarn.lock
|
|
20
|
-
|
|
21
|
-
- run: yarn install --immutable
|
|
22
|
-
|
|
23
|
-
- run: yarn build
|
|
24
|
-
|
|
25
|
-
- name: Create .npmrc for publishing
|
|
26
|
-
run: |
|
|
27
|
-
echo '//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}' > ~/.npmrc
|
|
28
|
-
|
|
29
|
-
- name: Set staging prerelease version
|
|
30
|
-
run: |
|
|
31
|
-
BASE=$(node -p "const [x,y,z]=require('./package.json').version.split('-')[0].split('.'); [x,y,+z+1].join('.')")
|
|
32
|
-
npm version "$BASE-staging.${{ github.run_number }}" --no-git-tag-version
|
|
33
|
-
node -p "'Publishing ' + require('./package.json').version"
|
|
34
|
-
|
|
35
|
-
- name: Publish to npm with staging tag
|
|
36
|
-
run: npm publish --tag staging --registry https://registry.npmjs.org
|
|
37
|
-
|
|
38
|
-
- name: Notify Discord on failure
|
|
39
|
-
if: failure()
|
|
40
|
-
env:
|
|
41
|
-
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
|
42
|
-
run: |
|
|
43
|
-
MESSAGE="@everyone :rotating_light: **Publish Staging** failed in \`${{ github.repository }}\` (\`${{ github.workflow }}\`)
|
|
44
|
-
${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
45
|
-
curl -s -X POST -H "Content-Type: application/json" \
|
|
46
|
-
-d "$(jq -n --arg content "$MESSAGE" '{content: $content}')" \
|
|
47
|
-
"$DISCORD_WEBHOOK_URL"
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
name: Publish
|
|
2
|
-
on:
|
|
3
|
-
workflow_run:
|
|
4
|
-
workflows: [CI]
|
|
5
|
-
branches: [main]
|
|
6
|
-
types: [completed]
|
|
7
|
-
|
|
8
|
-
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|
9
|
-
|
|
10
|
-
permissions:
|
|
11
|
-
contents: write
|
|
12
|
-
pull-requests: write
|
|
13
|
-
|
|
14
|
-
jobs:
|
|
15
|
-
publish:
|
|
16
|
-
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
17
|
-
runs-on: ubuntu-latest
|
|
18
|
-
steps:
|
|
19
|
-
- uses: actions/checkout@v4
|
|
20
|
-
|
|
21
|
-
- uses: actions/setup-node@v4
|
|
22
|
-
with:
|
|
23
|
-
node-version: 20.x
|
|
24
|
-
cache: "yarn" # Use yarn for caching
|
|
25
|
-
cache-dependency-path: yarn.lock # Cache Yarn lockfile
|
|
26
|
-
|
|
27
|
-
- run: yarn install --immutable # Install dependencies with immutable lockfile
|
|
28
|
-
|
|
29
|
-
- name: Create .npmrc for publishing
|
|
30
|
-
run: |
|
|
31
|
-
echo '//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}' > ~/.npmrc
|
|
32
|
-
|
|
33
|
-
- name: Create Release Pull Request or Publish
|
|
34
|
-
id: changesets
|
|
35
|
-
uses: changesets/action@v1
|
|
36
|
-
with:
|
|
37
|
-
publish: yarn release # Use yarn for publishing
|
|
38
|
-
env:
|
|
39
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|