@pgcorp/ui-kit 0.8.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +332 -9
  2. package/docs/getting-started.md +135 -0
  3. package/docs/public-api.md +53 -4
  4. package/docs/rich-document.md +216 -0
  5. package/docs/scroll-viewport.md +167 -0
  6. package/docs/theming.md +17 -0
  7. package/package.json +108 -50
  8. package/src/components/layout/SAppShell.vue +3 -1
  9. package/src/components/layout/SDockRegion.vue +5 -3
  10. package/src/components/layout/SResizeHandle.vue +45 -5
  11. package/src/components/layout/SWorkbenchPanelShell.vue +4 -2
  12. package/src/components/shared/_internal/SDialogSurface.css +23 -0
  13. package/src/components/shared/_internal/SDialogSurface.vue +9 -2
  14. package/src/components/shared/_internal/SToastItem.css +4 -0
  15. package/src/components/shared/_internal/SToastItem.vue +44 -8
  16. package/src/components/shared/_internal/STreeNode.vue +24 -11
  17. package/src/components/shared/_internal/dialogSurface.ts +7 -1
  18. package/src/components/shared/complex/SKanbanLane.vue +4 -2
  19. package/src/components/shared/containers/SCloudChromeRow.vue +3 -2
  20. package/src/components/shared/containers/SDrawer.css +11 -2
  21. package/src/components/shared/containers/SDrawer.vue +48 -9
  22. package/src/components/shared/containers/SModal.vue +5 -2
  23. package/src/components/shared/containers/SPanel.vue +4 -2
  24. package/src/components/shared/containers/SPopover.vue +7 -3
  25. package/src/components/shared/containers/SUiKitLocaleProvider.vue +57 -0
  26. package/src/components/shared/controls/SButton.css +14 -10
  27. package/src/components/shared/controls/SCombobox.vue +8 -6
  28. package/src/components/shared/controls/SComboboxTrigger.css +7 -4
  29. package/src/components/shared/controls/SComboboxTrigger.vue +5 -2
  30. package/src/components/shared/controls/SContextToggleButton.vue +6 -4
  31. package/src/components/shared/controls/SDragHandle.vue +8 -4
  32. package/src/components/shared/controls/SDropdownMenu.vue +7 -4
  33. package/src/components/shared/controls/SInputText.css +5 -4
  34. package/src/components/shared/controls/SListbox.vue +4 -2
  35. package/src/components/shared/controls/SSelect.vue +4 -2
  36. package/src/components/shared/controls/STextarea.ts +13 -0
  37. package/src/components/shared/controls/STextarea.vue +391 -37
  38. package/src/components/shared/controls/_internal/SInlineTokenSurface.vue +4 -2
  39. package/src/components/shared/data-display/SChart.vue +7 -5
  40. package/src/components/shared/data-display/SChip.vue +3 -1
  41. package/src/components/shared/data-display/SCodeBlock.css +4 -0
  42. package/src/components/shared/data-display/SCodeBlock.vue +46 -22
  43. package/src/components/shared/data-display/SCodeEditor.css +17 -0
  44. package/src/components/shared/data-display/SCodeEditor.vue +173 -8
  45. package/src/components/shared/data-display/SCodeSearchPanel.vue +48 -33
  46. package/src/components/shared/data-display/SCodeWorkspaceEditor.css +13 -0
  47. package/src/components/shared/data-display/SCodeWorkspaceEditor.vue +355 -0
  48. package/src/components/shared/data-display/SControlledToastViewport.css +89 -0
  49. package/src/components/shared/data-display/SControlledToastViewport.vue +205 -0
  50. package/src/components/shared/data-display/SCopyField.vue +12 -10
  51. package/src/components/shared/data-display/SDiffViewer.css +122 -0
  52. package/src/components/shared/data-display/SDiffViewer.vue +499 -0
  53. package/src/components/shared/data-display/SDocBlock.vue +99 -71
  54. package/src/components/shared/data-display/SExpandableText.vue +10 -8
  55. package/src/components/shared/data-display/SJsonTree.vue +4 -2
  56. package/src/components/shared/data-display/SLinkedSystemsList.vue +4 -2
  57. package/src/components/shared/data-display/SMessage.vue +6 -6
  58. package/src/components/shared/data-display/SRichDocument.css +8 -0
  59. package/src/components/shared/data-display/SRichDocument.vue +65 -0
  60. package/src/components/shared/data-display/SScrollViewport.css +53 -0
  61. package/src/components/shared/data-display/SScrollViewport.vue +470 -0
  62. package/src/components/shared/data-display/STable.vue +38 -19
  63. package/src/components/shared/data-display/SToastContainer.vue +22 -17
  64. package/src/components/shared/data-display/SVirtualList.ts +33 -0
  65. package/src/components/shared/data-display/SVirtualList.vue +321 -36
  66. package/src/components/shared/data-display/_internal/SCodeTokenLine.css +72 -0
  67. package/src/components/shared/data-display/_internal/SCodeTokenLine.vue +79 -0
  68. package/src/components/shared/data-display/_internal/SRichBlockNode.css +85 -0
  69. package/src/components/shared/data-display/_internal/SRichBlockNode.vue +282 -0
  70. package/src/components/shared/data-display/_internal/SRichInlineNode.css +6 -0
  71. package/src/components/shared/data-display/_internal/SRichInlineNode.vue +76 -0
  72. package/src/components/shared/data-display/_internal/SRichMath.css +42 -0
  73. package/src/components/shared/data-display/_internal/SRichMath.vue +102 -0
  74. package/src/components/shared/data-display/codeEditor.ts +200 -0
  75. package/src/components/shared/data-display/codeWorkspace.ts +233 -0
  76. package/src/components/shared/data-display/diff.ts +541 -0
  77. package/src/components/shared/data-display/richDocument.ts +876 -0
  78. package/src/components/shared/data-display/scrollViewport.ts +47 -0
  79. package/src/components/shared/data-display/toast.ts +194 -0
  80. package/src/components/shared/database/SDataGrid.vue +7 -4
  81. package/src/components/shared/database/SSqlEditor.vue +39 -39
  82. package/src/components/shared/feedback/SAsyncState.vue +3 -1
  83. package/src/components/shared/graph/SGraphViewport.vue +11 -9
  84. package/src/components/shared/navigation/SBreadcrumbs.vue +8 -5
  85. package/src/components/shared/navigation/SCatalogNavigator.vue +26 -20
  86. package/src/components/shared/navigation/STabList.vue +10 -6
  87. package/src/components/shared/navigation/STabs.vue +15 -11
  88. package/src/components/shared/navigation/SWizardSteps.vue +4 -2
  89. package/src/components/shared/persona/SPersonaProjectPicker.vue +31 -27
  90. package/src/components/shared/persona/SPersonaRunWorkbench.vue +39 -33
  91. package/src/components/shared/persona/_internal/SPersonaRunConsole.vue +8 -6
  92. package/src/components/shared/persona/_internal/labels.ts +66 -57
  93. package/src/components/shared/persona/presentation.ts +140 -110
  94. package/src/composables/useFloatingPosition.ts +39 -2
  95. package/src/composables/useUiKitLocale.ts +17 -0
  96. package/src/internal/codeHighlight.ts +110 -0
  97. package/src/internal/diffEngine.ts +464 -0
  98. package/src/internal/diffRuntime.ts +189 -0
  99. package/src/internal/feedbackPresentation.ts +33 -14
  100. package/src/internal/localeContext.ts +22 -0
  101. package/src/internal/ownedAttrs.ts +8 -0
  102. package/src/internal/runtimeContract.ts +11 -9
  103. package/src/internal/semanticSizing.ts +13 -0
  104. package/src/locales/catalog.ts +634 -0
  105. package/src/locales/locale.ts +472 -0
  106. package/src/locales/messages.generated.ts +1826 -0
  107. package/src/locales/messages.ts +150 -0
  108. package/src/stores/useNotifierStore.ts +61 -44
  109. package/src/styles/tokens.css +23 -2
  110. package/src/theme.ts +59 -32
  111. package/src/workers/diff.worker.ts +73 -0
  112. package/src/workers/diffProtocol.ts +155 -0
  113. package/src/components/shared/data-display/SToastContainer.css +0 -53
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgcorp/ui-kit",
3
- "version": "0.8.1",
3
+ "version": "0.10.0",
4
4
  "description": "Typed Vue 3 design system with accessible components, semantic themes, and workbench patterns.",
5
5
  "type": "module",
6
6
  "types": "./index.ts",
@@ -37,7 +37,7 @@
37
37
  "email": "remand-gambol4g@icloud.com"
38
38
  },
39
39
  "engines": {
40
- "node": ">=20.19.0",
40
+ "node": "^22.22.2 || ^24.15.0 || ^26.0.0",
41
41
  "npm": ">=10.9.2 <12"
42
42
  },
43
43
  "publishConfig": {
@@ -46,17 +46,21 @@
46
46
  },
47
47
  "scripts": {
48
48
  "audit:composition": "node ./scripts/check-composition.mjs --mode audit",
49
+ "audit:owned-strings": "node ./scripts/audit-kit-owned-strings.mjs",
49
50
  "build": "vite build",
50
51
  "check:composition": "node ./scripts/check-composition.mjs --mode check",
51
52
  "check:composition-contract": "node ./scripts/check-composition.mjs --mode contract",
53
+ "check:owned-strings": "node ./scripts/audit-kit-owned-strings.mjs --check",
52
54
  "check:proof": "node ./scripts/check-proof-contract.mjs",
53
55
  "check:proof-contract": "vitest --config ./vitest.config.ts --run src/__tests__/proof-contract.spec.ts src/__tests__/proof-sync.spec.ts",
54
56
  "check:proof-drift": "node ./scripts/sync-proof-contract.mjs --check",
55
57
  "check:package-exports": "node ./scripts/sync-package-exports.mjs --check",
58
+ "check:locale-runtime": "node ./scripts/sync-locale-runtime.mjs --check",
56
59
  "check:publish": "node ./scripts/check-publish-contract.mjs",
57
60
  "pack:dry-run": "npm pack --dry-run --json --cache ../../.cache/npm/ui-kit-publish",
58
61
  "smoke:package": "node ./scripts/smoke-published-package.mjs",
59
62
  "sync:package-exports": "node ./scripts/sync-package-exports.mjs --write",
63
+ "sync:locale-runtime": "node ./scripts/sync-locale-runtime.mjs --write",
60
64
  "sync:proof": "node ./scripts/sync-proof-contract.mjs --write",
61
65
  "type-check": "vue-tsc --noEmit -p tsconfig.json",
62
66
  "type-check:test": "vue-tsc --noEmit -p tsconfig.vitest.json",
@@ -87,6 +91,9 @@
87
91
  "composables/useSidebarPanelState": [
88
92
  "src/composables/useSidebarPanelState.ts"
89
93
  ],
94
+ "composables/useUiKitLocale": [
95
+ "src/composables/useUiKitLocale.ts"
96
+ ],
90
97
  "icons": [
91
98
  "src/components/icons/sputnigUiIcons.ts"
92
99
  ],
@@ -189,6 +196,9 @@
189
196
  "shared/containers/SSidebarSection.vue": [
190
197
  "src/components/shared/containers/SSidebarSection.vue"
191
198
  ],
199
+ "shared/containers/SUiKitLocaleProvider.vue": [
200
+ "src/components/shared/containers/SUiKitLocaleProvider.vue"
201
+ ],
192
202
  "shared/controls/menu": [
193
203
  "src/components/shared/controls/menu.ts"
194
204
  ],
@@ -267,15 +277,30 @@
267
277
  "shared/controls/SSwitch.vue": [
268
278
  "src/components/shared/controls/SSwitch.vue"
269
279
  ],
280
+ "shared/controls/STextarea": [
281
+ "src/components/shared/controls/STextarea.ts"
282
+ ],
270
283
  "shared/controls/STextarea.vue": [
271
284
  "src/components/shared/controls/STextarea.vue"
272
285
  ],
273
286
  "shared/data-display/chart": [
274
287
  "src/components/shared/data-display/chart.ts"
275
288
  ],
289
+ "shared/data-display/codeEditor": [
290
+ "src/components/shared/data-display/codeEditor.ts"
291
+ ],
292
+ "shared/data-display/codeWorkspace": [
293
+ "src/components/shared/data-display/codeWorkspace.ts"
294
+ ],
295
+ "shared/data-display/diff": [
296
+ "src/components/shared/data-display/diff.ts"
297
+ ],
276
298
  "shared/data-display/json": [
277
299
  "src/components/shared/data-display/json.ts"
278
300
  ],
301
+ "shared/data-display/richDocument": [
302
+ "src/components/shared/data-display/richDocument.ts"
303
+ ],
279
304
  "shared/data-display/SActionCard.vue": [
280
305
  "src/components/shared/data-display/SActionCard.vue"
281
306
  ],
@@ -303,9 +328,21 @@
303
328
  "shared/data-display/SCodeSearchPanel.vue": [
304
329
  "src/components/shared/data-display/SCodeSearchPanel.vue"
305
330
  ],
331
+ "shared/data-display/SCodeWorkspaceEditor.vue": [
332
+ "src/components/shared/data-display/SCodeWorkspaceEditor.vue"
333
+ ],
334
+ "shared/data-display/SControlledToastViewport.vue": [
335
+ "src/components/shared/data-display/SControlledToastViewport.vue"
336
+ ],
306
337
  "shared/data-display/SCopyField.vue": [
307
338
  "src/components/shared/data-display/SCopyField.vue"
308
339
  ],
340
+ "shared/data-display/scrollViewport": [
341
+ "src/components/shared/data-display/scrollViewport.ts"
342
+ ],
343
+ "shared/data-display/SDiffViewer.vue": [
344
+ "src/components/shared/data-display/SDiffViewer.vue"
345
+ ],
309
346
  "shared/data-display/SDocBlock.vue": [
310
347
  "src/components/shared/data-display/SDocBlock.vue"
311
348
  ],
@@ -336,6 +373,12 @@
336
373
  "shared/data-display/SProgressIndicator.vue": [
337
374
  "src/components/shared/data-display/SProgressIndicator.vue"
338
375
  ],
376
+ "shared/data-display/SRichDocument.vue": [
377
+ "src/components/shared/data-display/SRichDocument.vue"
378
+ ],
379
+ "shared/data-display/SScrollViewport.vue": [
380
+ "src/components/shared/data-display/SScrollViewport.vue"
381
+ ],
339
382
  "shared/data-display/SSectionHeader.vue": [
340
383
  "src/components/shared/data-display/SSectionHeader.vue"
341
384
  ],
@@ -366,6 +409,9 @@
366
409
  "shared/data-display/table": [
367
410
  "src/components/shared/data-display/table.ts"
368
411
  ],
412
+ "shared/data-display/toast": [
413
+ "src/components/shared/data-display/toast.ts"
414
+ ],
369
415
  "shared/database/SDataGrid.vue": [
370
416
  "src/components/shared/database/SDataGrid.vue"
371
417
  ],
@@ -449,6 +495,7 @@
449
495
  "./composables/useFloatingPosition": "./src/composables/useFloatingPosition.ts",
450
496
  "./composables/useNotifier": "./src/composables/useNotifier.ts",
451
497
  "./composables/useSidebarPanelState": "./src/composables/useSidebarPanelState.ts",
498
+ "./composables/useUiKitLocale": "./src/composables/useUiKitLocale.ts",
452
499
  "./icons": "./src/components/icons/sputnigUiIcons.ts",
453
500
  "./layout/SAppShell.vue": "./src/components/layout/SAppShell.vue",
454
501
  "./layout/SDockRegion.vue": "./src/components/layout/SDockRegion.vue",
@@ -484,6 +531,7 @@
484
531
  "./shared/containers/SPopover.vue": "./src/components/shared/containers/SPopover.vue",
485
532
  "./shared/containers/SSidebarGroup.vue": "./src/components/shared/containers/SSidebarGroup.vue",
486
533
  "./shared/containers/SSidebarSection.vue": "./src/components/shared/containers/SSidebarSection.vue",
534
+ "./shared/containers/SUiKitLocaleProvider.vue": "./src/components/shared/containers/SUiKitLocaleProvider.vue",
487
535
  "./shared/controls/menu": "./src/components/shared/controls/menu.ts",
488
536
  "./shared/controls/SButton.vue": "./src/components/shared/controls/SButton.vue",
489
537
  "./shared/controls/SCheckbox.vue": "./src/components/shared/controls/SCheckbox.vue",
@@ -510,9 +558,14 @@
510
558
  "./shared/controls/SSegmentedControl.vue": "./src/components/shared/controls/SSegmentedControl.vue",
511
559
  "./shared/controls/SSelect.vue": "./src/components/shared/controls/SSelect.vue",
512
560
  "./shared/controls/SSwitch.vue": "./src/components/shared/controls/SSwitch.vue",
561
+ "./shared/controls/STextarea": "./src/components/shared/controls/STextarea.ts",
513
562
  "./shared/controls/STextarea.vue": "./src/components/shared/controls/STextarea.vue",
514
563
  "./shared/data-display/chart": "./src/components/shared/data-display/chart.ts",
564
+ "./shared/data-display/codeEditor": "./src/components/shared/data-display/codeEditor.ts",
565
+ "./shared/data-display/codeWorkspace": "./src/components/shared/data-display/codeWorkspace.ts",
566
+ "./shared/data-display/diff": "./src/components/shared/data-display/diff.ts",
515
567
  "./shared/data-display/json": "./src/components/shared/data-display/json.ts",
568
+ "./shared/data-display/richDocument": "./src/components/shared/data-display/richDocument.ts",
516
569
  "./shared/data-display/SActionCard.vue": "./src/components/shared/data-display/SActionCard.vue",
517
570
  "./shared/data-display/SActionList.vue": "./src/components/shared/data-display/SActionList.vue",
518
571
  "./shared/data-display/SActionListItem.vue": "./src/components/shared/data-display/SActionListItem.vue",
@@ -522,7 +575,11 @@
522
575
  "./shared/data-display/SCodeBlock.vue": "./src/components/shared/data-display/SCodeBlock.vue",
523
576
  "./shared/data-display/SCodeEditor.vue": "./src/components/shared/data-display/SCodeEditor.vue",
524
577
  "./shared/data-display/SCodeSearchPanel.vue": "./src/components/shared/data-display/SCodeSearchPanel.vue",
578
+ "./shared/data-display/SCodeWorkspaceEditor.vue": "./src/components/shared/data-display/SCodeWorkspaceEditor.vue",
579
+ "./shared/data-display/SControlledToastViewport.vue": "./src/components/shared/data-display/SControlledToastViewport.vue",
525
580
  "./shared/data-display/SCopyField.vue": "./src/components/shared/data-display/SCopyField.vue",
581
+ "./shared/data-display/scrollViewport": "./src/components/shared/data-display/scrollViewport.ts",
582
+ "./shared/data-display/SDiffViewer.vue": "./src/components/shared/data-display/SDiffViewer.vue",
526
583
  "./shared/data-display/SDocBlock.vue": "./src/components/shared/data-display/SDocBlock.vue",
527
584
  "./shared/data-display/SEmptyState.vue": "./src/components/shared/data-display/SEmptyState.vue",
528
585
  "./shared/data-display/SExpandableText.vue": "./src/components/shared/data-display/SExpandableText.vue",
@@ -533,6 +590,8 @@
533
590
  "./shared/data-display/SMetricCard.vue": "./src/components/shared/data-display/SMetricCard.vue",
534
591
  "./shared/data-display/SProgressBar.vue": "./src/components/shared/data-display/SProgressBar.vue",
535
592
  "./shared/data-display/SProgressIndicator.vue": "./src/components/shared/data-display/SProgressIndicator.vue",
593
+ "./shared/data-display/SRichDocument.vue": "./src/components/shared/data-display/SRichDocument.vue",
594
+ "./shared/data-display/SScrollViewport.vue": "./src/components/shared/data-display/SScrollViewport.vue",
536
595
  "./shared/data-display/SSectionHeader.vue": "./src/components/shared/data-display/SSectionHeader.vue",
537
596
  "./shared/data-display/SStatus.vue": "./src/components/shared/data-display/SStatus.vue",
538
597
  "./shared/data-display/STable.vue": "./src/components/shared/data-display/STable.vue",
@@ -543,6 +602,7 @@
543
602
  "./shared/data-display/SVirtualList": "./src/components/shared/data-display/SVirtualList.ts",
544
603
  "./shared/data-display/SVirtualList.vue": "./src/components/shared/data-display/SVirtualList.vue",
545
604
  "./shared/data-display/table": "./src/components/shared/data-display/table.ts",
605
+ "./shared/data-display/toast": "./src/components/shared/data-display/toast.ts",
546
606
  "./shared/database/SDataGrid.vue": "./src/components/shared/database/SDataGrid.vue",
547
607
  "./shared/database/SSqlEditor.vue": "./src/components/shared/database/SSqlEditor.vue",
548
608
  "./shared/feedback/SAsyncState.vue": "./src/components/shared/feedback/SAsyncState.vue",
@@ -570,64 +630,62 @@
570
630
  "./variants": "./src/variants.ts"
571
631
  },
572
632
  "peerDependencies": {
573
- "pinia": "^3.0.4",
574
- "vue": "^3.5.0",
575
- "vue-router": "^5.0.0"
633
+ "@vue/devtools-api": "^8.2.1",
634
+ "pinia": "^4.0.3",
635
+ "vue": "^3.5.43",
636
+ "vue-router": "^5.3.1"
576
637
  },
577
638
  "dependencies": {
578
- "@codemirror/autocomplete": "^6.20.1",
579
- "@codemirror/language": "^6.11.3",
580
- "@codemirror/legacy-modes": "^6.5.2",
581
- "@codemirror/lint": "^6.9.5",
582
- "@codemirror/state": "^6.5.4",
639
+ "@codemirror/autocomplete": "^6.20.3",
640
+ "@codemirror/language": "^6.12.4",
641
+ "@codemirror/legacy-modes": "^6.5.4",
642
+ "@codemirror/lint": "^6.9.7",
643
+ "@codemirror/state": "^6.7.5",
583
644
  "@codemirror/theme-one-dark": "^6.1.3",
584
- "@codemirror/view": "^6.39.15",
585
- "@uiw/codemirror-extensions-langs": "^4.25.8",
645
+ "@codemirror/view": "^6.43.12",
646
+ "@uiw/codemirror-extensions-langs": "^4.25.11",
586
647
  "codemirror": "6.0.2",
587
648
  "codemirror-lang-makefile": "^0.1.1",
588
- "dompurify": "^3.4.13",
649
+ "dompurify": "^3.4.16",
589
650
  "graphology": "^0.26.0",
590
- "highlight.js": "^11.11.1",
591
- "@lucide/vue": "^1.16.0",
592
- "@tailwindcss/typography": "^0.5.19",
593
- "marked": "^17.0.3",
651
+ "highlight.js": "^11.12.0",
652
+ "katex": "0.18.7",
653
+ "@lucide/vue": "^1.47.0",
654
+ "@tailwindcss/typography": "^0.5.20",
655
+ "marked": "^18.0.13",
594
656
  "sigma": "^3.0.3",
595
- "tailwindcss": "^4.2.0",
596
- "uuid": "^13.0.0",
657
+ "tailwindcss": "^4.3.3",
658
+ "uuid": "^14.0.2",
597
659
  "vue-codemirror": "^6.1.1"
598
660
  },
599
661
  "devDependencies": {
600
- "@storybook/vue3-vite": "10.5.3",
601
- "@tailwindcss/postcss": "^4.2.0",
602
- "@types/node": "^25.3.0",
603
- "@vitejs/plugin-vue": "^6.0.4",
604
- "@vitest/coverage-v8": "^4.0.18",
605
- "@vitest/eslint-plugin": "1.6.20",
606
- "@vue/compiler-dom": "3.5.39",
607
- "@vue/compiler-sfc": "3.5.39",
662
+ "@storybook/vue3-vite": "10.6.0",
663
+ "@tailwindcss/postcss": "^4.3.3",
664
+ "@types/node": "^22.20.4",
665
+ "@vitejs/plugin-vue": "^6.0.9",
666
+ "@vitest/coverage-v8": "^5.0.1",
667
+ "@vitest/eslint-plugin": "1.6.27",
668
+ "@vue/compiler-dom": "3.5.43",
669
+ "@vue/compiler-sfc": "3.5.43",
670
+ "@vue/devtools-api": "^8.2.1",
608
671
  "@vue/eslint-config-prettier": "^10.2.0",
609
- "@vue/eslint-config-typescript": "^14.7.0",
610
- "@vue/test-utils": "^2.4.6",
611
- "date-fns": "^4.1.0",
612
- "eslint": "^10.0.0",
613
- "eslint-plugin-vue": "^10.8.0",
614
- "jsdom": "^28.1.0",
615
- "pinia": "^3.0.4",
616
- "postcss": "8.5.26",
617
- "postcss-selector-parser": "7.1.4",
618
- "storybook": "10.5.3",
619
- "typescript": "^5.9.3",
620
- "vite": "^7.3.1",
621
- "vite-plugin-dts": "^4.5.4",
622
- "vitest": "^4.0.18",
623
- "vue": "^3.5.28",
624
- "vue-router": "^5.0.3",
625
- "vue-tsc": "^3.2.4"
626
- },
627
- "overrides": {
628
- "glob": "13.0.6",
629
- "js-beautify": {
630
- "glob": "13.0.6"
631
- }
672
+ "@vue/test-utils": "2.5.1",
673
+ "date-fns": "^4.4.0",
674
+ "eslint": "^10.11.0",
675
+ "eslint-plugin-vue": "^10.11.0",
676
+ "jsdom": "^30.1.0",
677
+ "pinia": "^4.0.3",
678
+ "postcss": "8.5.28",
679
+ "postcss-selector-parser": "7.1.6",
680
+ "storybook": "10.6.0",
681
+ "typescript": "^6.0.3",
682
+ "typescript-eslint": "^8.70.0",
683
+ "vite": "^8.3.0",
684
+ "vite-plugin-dts": "^5.1.0",
685
+ "vitest": "^5.0.1",
686
+ "vue": "^3.5.43",
687
+ "vue-eslint-parser": "^10.4.1",
688
+ "vue-router": "^5.3.1",
689
+ "vue-tsc": "^3.3.11"
632
690
  }
633
691
  }
@@ -4,6 +4,7 @@ import type { RouteLocationRaw } from 'vue-router'
4
4
  import { hasOwn } from '../../internal/es2020'
5
5
  import { useOwnedAttrs } from '../../internal/ownedAttrs'
6
6
  import { validateNonEmptyString } from '../../internal/runtimeContract'
7
+ import { useUiKitLocale } from '../../composables/useUiKitLocale'
7
8
  import SBadge from '../shared/data-display/SBadge.vue'
8
9
  import SPanel from '../shared/containers/SPanel.vue'
9
10
  import SLink from '../shared/controls/SLink.vue'
@@ -57,6 +58,7 @@ interface RuntimeProps extends SharedProps {
57
58
  }
58
59
 
59
60
  const props = defineProps<RuntimeProps>()
61
+ const { t } = useUiKitLocale()
60
62
  function requireComponentInstance() {
61
63
  const instance = getCurrentInstance()
62
64
  if (!instance) throw new Error('SAppShell: component instance unavailable during setup')
@@ -121,7 +123,7 @@ const shell = computed<ResolvedShell>(() => {
121
123
  navigationLabel: validateNonEmptyString(
122
124
  'SAppShell',
123
125
  'navigationLabel',
124
- props.navigationLabel ?? 'Основная навигация',
126
+ props.navigationLabel ?? t('navigation.main'),
125
127
  ),
126
128
  pageBadgeLabel: props.pageBadgeLabel ?? '',
127
129
  pageBadgeSeverity: props.pageBadgeSeverity ?? 'info',
@@ -39,6 +39,7 @@
39
39
 
40
40
  <script setup lang="ts">
41
41
  import { computed, ref, type CSSProperties } from 'vue'
42
+ import { useUiKitLocale } from '../../composables/useUiKitLocale'
42
43
  import { useOwnedAttrs } from '../../internal/ownedAttrs'
43
44
  import {
44
45
  validateBoolean,
@@ -79,6 +80,7 @@ const props = withDefaults(defineProps<{
79
80
  hideResizeHandleOnNarrow: false,
80
81
  responsiveSize: 'fixed',
81
82
  })
83
+ const { t } = useUiKitLocale()
82
84
 
83
85
  const emit = defineEmits<{
84
86
  (event: 'resize-start', pointerEvent: PointerEvent): void
@@ -122,9 +124,9 @@ const resolvedResizeLabel = computed(() => {
122
124
  if (props.resizeLabel !== undefined) {
123
125
  return validateNonEmptyString('SDockRegion', 'resizeLabel', props.resizeLabel)
124
126
  }
125
- if (contract.value.placement === 'bottom') return 'Изменить высоту нижней панели'
126
- if (contract.value.placement === 'left') return 'Изменить ширину левой панели'
127
- return 'Изменить ширину правой панели'
127
+ if (contract.value.placement === 'bottom') return t('layout.resizeBottomPanel')
128
+ if (contract.value.placement === 'left') return t('layout.resizeLeftPanel')
129
+ return t('layout.resizeRightPanel')
128
130
  })
129
131
 
130
132
  function handleResizeStart(event: PointerEvent): void {
@@ -14,6 +14,9 @@
14
14
  :data-testid="dataTestId"
15
15
  :data-resizing="effectiveResizing || undefined"
16
16
  :data-hidden-on-narrow="hiddenOnNarrow || undefined"
17
+ :data-hitbox="validatedHitbox"
18
+ :data-orientation="orientation"
19
+ :data-variant="variant"
17
20
  :class="handleClasses"
18
21
  @pointerdown="handlePointerDown"
19
22
  @keydown="handleKeydown"
@@ -30,10 +33,14 @@ import {
30
33
  acquirePointerInteractionLease,
31
34
  type PointerInteractionLease,
32
35
  } from '../../internal/pointerInteractionLease'
33
- import { validateNonEmptyString } from '../../internal/runtimeContract'
36
+ import { validateExactString, validateNonEmptyString } from '../../internal/runtimeContract'
34
37
 
35
38
  defineOptions({ inheritAttrs: false })
36
39
 
40
+ export type SResizeHandleHitbox = 'compact' | 'standard' | 'spacious'
41
+
42
+ const RESIZE_HANDLE_HITBOXES = ['compact', 'standard', 'spacious'] as const satisfies readonly SResizeHandleHitbox[]
43
+
37
44
  const props = withDefaults(defineProps<{
38
45
  orientation: 'vertical' | 'horizontal'
39
46
  variant?: 'inline' | 'overlay'
@@ -48,6 +55,8 @@ const props = withDefaults(defineProps<{
48
55
  max?: number
49
56
  step?: number
50
57
  pointerScale?: number
58
+ /** Семантическая толщина pointer/focus hitbox; visual divider остаётся однопиксельным. */
59
+ hitbox?: SResizeHandleHitbox
51
60
  }>(), {
52
61
  orientation: 'vertical',
53
62
  variant: 'inline',
@@ -61,6 +70,7 @@ const props = withDefaults(defineProps<{
61
70
  max: 100,
62
71
  step: 10,
63
72
  pointerScale: 1,
73
+ hitbox: undefined,
64
74
  })
65
75
 
66
76
  const emit = defineEmits<{
@@ -83,6 +93,12 @@ const ownedAttrs = useOwnedAttrs({ component: 'SResizeHandle', owner: 'native se
83
93
  useInteractiveLeafRegistration({ owner: 'SResizeHandle' })
84
94
  const effectiveResizing = computed(() => props.resizing || pointerResizeState.value !== null)
85
95
  const validatedLabel = computed(() => validateNonEmptyString('SResizeHandle', 'label', props.label))
96
+ const validatedHitbox = computed(() => validateExactString(
97
+ 'SResizeHandle',
98
+ 'hitbox',
99
+ props.hitbox ?? (props.variant === 'overlay' ? 'spacious' : 'compact'),
100
+ RESIZE_HANDLE_HITBOXES,
101
+ ))
86
102
  const validatedRange = computed(() => {
87
103
  assertRangeContract()
88
104
  return { value: props.value, min: props.min, max: props.max }
@@ -225,11 +241,11 @@ const handleClasses = computed(() => [
225
241
  : 'pointer-events-auto absolute z-[var(--s-layer-floating)] items-center justify-center',
226
242
  props.orientation === 'vertical'
227
243
  ? props.variant === 'inline'
228
- ? 'w-1.5 self-stretch cursor-col-resize items-stretch justify-center'
229
- : 'inset-y-3 left-2 w-8 -translate-x-1/2 cursor-col-resize'
244
+ ? 'self-stretch cursor-col-resize items-stretch justify-center'
245
+ : 'inset-y-3 left-2 -translate-x-1/2 cursor-col-resize'
230
246
  : props.variant === 'inline'
231
- ? 'h-1.5 w-full cursor-row-resize items-center justify-stretch'
232
- : 'inset-x-5 top-0 h-8 -translate-y-1/2 cursor-row-resize',
247
+ ? 'w-full cursor-row-resize items-center justify-stretch'
248
+ : 'inset-x-5 top-0 -translate-y-1/2 cursor-row-resize',
233
249
  ])
234
250
 
235
251
  const lineClasses = computed(() =>
@@ -244,6 +260,30 @@ const lineClasses = computed(() =>
244
260
  </script>
245
261
 
246
262
  <style scoped>
263
+ .s-resize-handle[data-orientation='vertical'][data-hitbox='compact'] {
264
+ width: var(--s-resize-handle-hitbox-compact);
265
+ }
266
+
267
+ .s-resize-handle[data-orientation='vertical'][data-hitbox='standard'] {
268
+ width: var(--s-resize-handle-hitbox-standard);
269
+ }
270
+
271
+ .s-resize-handle[data-orientation='vertical'][data-hitbox='spacious'] {
272
+ width: var(--s-resize-handle-hitbox-spacious);
273
+ }
274
+
275
+ .s-resize-handle[data-orientation='horizontal'][data-hitbox='compact'] {
276
+ height: var(--s-resize-handle-hitbox-compact);
277
+ }
278
+
279
+ .s-resize-handle[data-orientation='horizontal'][data-hitbox='standard'] {
280
+ height: var(--s-resize-handle-hitbox-standard);
281
+ }
282
+
283
+ .s-resize-handle[data-orientation='horizontal'][data-hitbox='spacious'] {
284
+ height: var(--s-resize-handle-hitbox-spacious);
285
+ }
286
+
247
287
  .s-resize-handle:focus-visible {
248
288
  outline: var(--s-focus-ring-width) solid var(--s-focus-ring-color);
249
289
  outline-offset: var(--s-focus-ring-offset);
@@ -91,6 +91,7 @@
91
91
 
92
92
  <script setup lang="ts">
93
93
  import { computed, onBeforeUnmount, onMounted, ref, useSlots, watch } from 'vue'
94
+ import { useUiKitLocale } from '../../composables/useUiKitLocale'
94
95
  import SAsyncState from '../shared/feedback/SAsyncState.vue'
95
96
  import { useOwnedAttrs } from '../../internal/ownedAttrs'
96
97
  import {
@@ -130,6 +131,7 @@ const props = withDefaults(defineProps<{
130
131
  secondaryStickyHeader: false,
131
132
  secondaryResponsiveStack: false,
132
133
  })
134
+ const { t } = useUiKitLocale()
133
135
 
134
136
  const slots = useSlots()
135
137
  const ownedAttrs = useOwnedAttrs({ component: 'SWorkbenchPanelShell', owner: 'workbench panel root' })
@@ -170,8 +172,8 @@ const showSecondary = computed(() =>
170
172
  const isBottomDock = computed(() => props.secondaryPlacement === 'bottom-dock')
171
173
  const dockPlacement = computed<'right' | 'bottom'>(() => isBottomDock.value ? 'bottom' : 'right')
172
174
  const secondaryResizeLabel = computed(() => isBottomDock.value
173
- ? 'Изменить высоту нижней панели'
174
- : 'Изменить ширину боковой панели')
175
+ ? t('layout.resizeBottomPanel')
176
+ : t('layout.resizeSidePanel'))
175
177
  const secondaryResizeTestId = computed(() => isBottomDock.value
176
178
  ? 'workbench-shell-resize-handle-bottom'
177
179
  : 'workbench-shell-resize-handle-right')
@@ -4,6 +4,11 @@
4
4
  box-shadow: var(--s-elevation-overlay);
5
5
  }
6
6
 
7
+ .s-dialog-surface:focus-visible {
8
+ outline: var(--s-focus-ring-width) solid var(--s-focus-ring-color);
9
+ outline-offset: var(--s-focus-ring-inset-offset);
10
+ }
11
+
7
12
  .s-dialog-surface[data-presentation='modal'] {
8
13
  @apply w-full transform overflow-hidden rounded-2xl p-6 text-left align-middle transition-all;
9
14
  @apply bg-surface-0 dark:bg-surface-800;
@@ -104,6 +109,24 @@
104
109
  max-width: 44rem;
105
110
  }
106
111
 
112
+ .s-dialog-surface[data-presentation='drawer'][data-placement='bottom'] {
113
+ @apply max-w-none rounded-t-2xl border-l-0 border-t border-surface-200 dark:border-surface-700;
114
+ width: 100%;
115
+ max-height: calc(100dvh - 1rem);
116
+ }
117
+
118
+ .s-dialog-surface[data-presentation='drawer'][data-placement='bottom'][data-size='sm'] {
119
+ height: 50dvh;
120
+ }
121
+
122
+ .s-dialog-surface[data-presentation='drawer'][data-placement='bottom'][data-size='md'] {
123
+ height: 70dvh;
124
+ }
125
+
126
+ .s-dialog-surface[data-presentation='drawer'][data-placement='bottom'][data-size='lg'] {
127
+ height: 90dvh;
128
+ }
129
+
107
130
  .s-dialog-surface[data-presentation='drawer'] .s-dialog-surface__header {
108
131
  @apply flex items-start gap-3 border-b border-surface-200 px-5 py-4 dark:border-surface-700 md:px-6;
109
132
  }
@@ -7,6 +7,7 @@
7
7
  :data-presentation="presentation.kind"
8
8
  :data-layout="surfaceLayout"
9
9
  :data-size="presentation.size"
10
+ :data-placement="drawerPresentation?.placement"
10
11
  :data-surface="modalPresentation?.surface"
11
12
  :data-scroll="modalPresentation?.scrollBehavior"
12
13
  tabindex="-1"
@@ -25,7 +26,7 @@
25
26
  icon-only
26
27
  appearance="text"
27
28
  size="sm"
28
- aria-label="Закрыть"
29
+ :aria-label="t('dialog.close')"
29
30
  @click="requestClose"
30
31
  />
31
32
  </component>
@@ -54,6 +55,7 @@
54
55
 
55
56
  <script setup lang="ts">
56
57
  import { computed, useId, useSlots, type ComponentPublicInstance } from 'vue'
58
+ import { useUiKitLocale } from '../../../composables/useUiKitLocale'
57
59
 
58
60
  import { X } from '../../icons/sputnigUiIcons'
59
61
  import SButton from '../controls/SButton.vue'
@@ -77,6 +79,7 @@ const props = defineProps<{
77
79
  const emit = defineEmits<{
78
80
  'request-close': []
79
81
  }>()
82
+ const { t } = useUiKitLocale()
80
83
 
81
84
  defineSlots<{
82
85
  header?: () => unknown
@@ -95,17 +98,21 @@ const isModal = computed(() => props.presentation.kind === 'modal')
95
98
  const modalPresentation = computed<ModalDialogSurfacePresentation | null>(() => (
96
99
  props.presentation.kind === 'modal' ? props.presentation : null
97
100
  ))
101
+ const drawerPresentation = computed(() => (
102
+ props.presentation.kind === 'drawer' ? props.presentation : null
103
+ ))
98
104
  const hasHeader = computed(() => Boolean(props.title || slots.header))
99
105
  const hasSplitFooter = computed(() => isModal.value && Boolean(slots['footer-start'] || slots['footer-end']))
100
106
  const hasFooter = computed(() => hasSplitFooter.value || Boolean(slots.footer))
101
107
  const rootTag = 'div'
102
108
  const headerTag = computed(() => (isModal.value ? 'div' : 'header'))
103
109
  const headingTag = computed(() => (isModal.value ? 'h3' : 'h2'))
104
- type DialogSurfaceLayout = 'contained' | 'fullscreen' | 'side-panel' | 'mobile-fullscreen'
110
+ type DialogSurfaceLayout = 'contained' | 'fullscreen' | 'side-panel' | 'mobile-fullscreen' | 'bottom-sheet'
105
111
 
106
112
  const surfaceLayout = computed<DialogSurfaceLayout>(() => {
107
113
  const presentation = props.presentation
108
114
  if (presentation.kind === 'drawer') {
115
+ if (presentation.placement === 'bottom') return 'bottom-sheet'
109
116
  return presentation.mobileFullScreen ? 'mobile-fullscreen' : 'side-panel'
110
117
  }
111
118
  return presentation.fullscreen || presentation.size === 'full' ? 'fullscreen' : 'contained'
@@ -28,6 +28,10 @@
28
28
  word-break: break-word;
29
29
  }
30
30
 
31
+ .s-toast-actions {
32
+ @apply mt-2 flex flex-wrap gap-2;
33
+ }
34
+
31
35
  .s-toast-close {
32
36
  @apply ml-auto shrink-0;
33
37
  }