diff --git a/apps/storybook/src/stories/core/BoxGridSelection.stories.js b/apps/storybook/src/stories/core/BoxGridSelection.stories.js
new file mode 100644
index 00000000..2d36d3e5
--- /dev/null
+++ b/apps/storybook/src/stories/core/BoxGridSelection.stories.js
@@ -0,0 +1,197 @@
+import BoxGridSelection from '@aziontech/webkit/box-grid-selection'
+import Tag from '@aziontech/webkit/tag'
+
+export default {
+ title: 'Core/BoxGridSelection',
+ component: BoxGridSelection,
+ tags: ['autodocs'],
+ argTypes: {
+ modelValue: {
+ control: 'text',
+ description: 'Currently selected item value (supports v-model)'
+ },
+ items: {
+ control: 'object',
+ description: 'Array of items with {value, icon, description, disabled?, ariaLabel?}'
+ },
+ disabled: {
+ control: 'boolean',
+ description: 'Disables all selections'
+ },
+ columns: {
+ control: { type: 'number', min: 1, max: 4 },
+ description: 'Number of grid columns (1-4, default: 3)'
+ }
+ }
+}
+
+const planItems = [
+ {
+ value: 'hobby',
+ icon: 'pi pi-sparkles',
+ description: 'For learning and small personal projects.',
+ tag: 'Hobby Plan'
+ },
+ {
+ value: 'pro',
+ icon: 'pi pi-chart-line',
+ description: 'For professional or commercial applications.',
+ tag: 'Pro Plan'
+ },
+ {
+ value: 'scale',
+ icon: 'pi pi-file-check',
+ description: 'For businesses requiring advanced security and compliance.',
+ tag: 'Scale Plan'
+ }
+]
+
+const basicItems = [
+ { value: 'option1', icon: 'pi pi-check', description: 'First option description' },
+ { value: 'option2', icon: 'pi pi-times', description: 'Second option description' },
+ { value: 'option3', icon: 'pi pi-star', description: 'Third option description' }
+]
+
+export const PlanSelection = {
+ args: {
+ modelValue: 'hobby',
+ columns: 3,
+ items: planItems
+ },
+ render: (args) => ({
+ components: { BoxGridSelection, Tag },
+ setup() {
+ return { args }
+ },
+ template: `
+
+
+
+
+
+ `
+ })
+}
+
+export const Default = {
+ args: {
+ modelValue: 'option1',
+ columns: 3,
+ items: basicItems
+ }
+}
+
+export const WithTwoColumns = {
+ args: {
+ modelValue: 'option1',
+ columns: 2,
+ items: [
+ { value: 'option1', icon: 'pi pi-desktop', description: 'Desktop application' },
+ { value: 'option2', icon: 'pi pi-mobile', description: 'Mobile application' }
+ ]
+ }
+}
+
+export const WithFourColumns = {
+ args: {
+ modelValue: 'option2',
+ columns: 4,
+ items: [
+ { value: 'option1', icon: 'pi pi-cloud', description: 'Cloud storage' },
+ { value: 'option2', icon: 'pi pi-database', description: 'Database service' },
+ { value: 'option3', icon: 'pi pi-server', description: 'Server hosting' },
+ { value: 'option4', icon: 'pi pi-shield', description: 'Security suite' }
+ ]
+ }
+}
+
+export const Disabled = {
+ args: {
+ modelValue: 'option1',
+ columns: 3,
+ items: basicItems,
+ disabled: true
+ }
+}
+
+export const WithDisabledItem = {
+ args: {
+ modelValue: 'option1',
+ columns: 3,
+ items: [
+ { value: 'option1', icon: 'pi pi-check', description: 'Available option' },
+ { value: 'option2', icon: 'pi pi-times', description: 'Unavailable option', disabled: true },
+ { value: 'option3', icon: 'pi pi-star', description: 'Available option' }
+ ]
+ }
+}
+
+export const Interactive = {
+ args: {
+ modelValue: 'hobby',
+ columns: 3,
+ items: planItems
+ },
+ render: (args) => ({
+ components: { BoxGridSelection, Tag },
+ data() {
+ return {
+ selectedValue: 'hobby'
+ }
+ },
+ methods: {
+ handleChange(item) {
+ console.log('Selected:', item)
+ }
+ },
+ template: `
+
+
+
+
+
+
+
+ Selected plan: {{ selectedValue }}
+
+
+ `
+ })
+}
+
+export const WithoutIcons = {
+ args: {
+ modelValue: 'basic',
+ columns: 3,
+ items: [
+ { value: 'basic', description: 'Basic tier with essential features' },
+ { value: 'standard', description: 'Standard tier with more features' },
+ { value: 'premium', description: 'Premium tier with all features' }
+ ]
+ }
+}
+
+export const SingleColumn = {
+ args: {
+ modelValue: 'option1',
+ columns: 1,
+ items: [
+ { value: 'option1', icon: 'pi pi-upload', description: 'Upload files from your computer' },
+ { value: 'option2', icon: 'pi pi-cloud-upload', description: 'Import from cloud storage' },
+ { value: 'option3', icon: 'pi pi-link', description: 'Import from URL' }
+ ]
+ }
+}
diff --git a/packages/theme/src/tailwind/semantic-colors-plugin.js b/packages/theme/src/tailwind/semantic-colors-plugin.js
index fd4e40eb..12c98f0c 100644
--- a/packages/theme/src/tailwind/semantic-colors-plugin.js
+++ b/packages/theme/src/tailwind/semantic-colors-plugin.js
@@ -18,11 +18,11 @@
// Lazy-require to avoid hard dependency for consumers
const plugin = (() => {
try {
- return require('tailwindcss/plugin');
+ return require('tailwindcss/plugin')
} catch {
- return (handler) => handler;
+ return (handler) => handler
}
-})();
+})()
/**
* Generate semantic color utilities
@@ -45,8 +45,8 @@ export const semanticColors = () => {
'.text-warning': { color: 'var(--text-warning)' },
'.text-warningHover': { color: 'var(--text-warningHover)' },
'.text-success': { color: 'var(--text-success)' },
- '.text-successHover': { color: 'var(--text-successHover)' },
- };
+ '.text-successHover': { color: 'var(--text-successHover)' }
+ }
const bgColors = {
'.bg-surfaceRaised': { 'background-color': 'var(--background-surfaceRaised)' },
@@ -62,7 +62,8 @@ export const semanticColors = () => {
'.bg-backdrop': { 'background-color': 'var(--background-backdrop)' },
'.bg-primary': { 'background-color': 'var(--background-primary)' },
'.bg-primaryHover': { 'background-color': 'var(--background-primaryHover)' },
- };
+ '.bg-primary-mask': { 'background-color': 'var(--background-primaryMask)' }
+ }
const borderColors = {
'.border-default': { 'border-color': 'var(--border-default)' },
@@ -77,14 +78,23 @@ export const semanticColors = () => {
'.border-primary': { 'border-color': 'var(--border-primary)' },
'.border-primaryHover': { 'border-color': 'var(--border-primaryHover)' },
'.border-accent': { 'border-color': 'var(--border-accent)' },
- '.border-accentHover': { 'border-color': 'var(--border-accentHover)' },
- };
+ '.border-accentHover': { 'border-color': 'var(--border-accentHover)' }
+ }
- const variants = ['responsive', 'hover', 'dark', 'before', 'after', 'focus', 'active', 'disabled'];
- addUtilities(textColors, variants);
- addUtilities(bgColors, variants);
- addUtilities(borderColors, variants);
- });
-};
+ const variants = [
+ 'responsive',
+ 'hover',
+ 'dark',
+ 'before',
+ 'after',
+ 'focus',
+ 'active',
+ 'disabled'
+ ]
+ addUtilities(textColors, variants)
+ addUtilities(bgColors, variants)
+ addUtilities(borderColors, variants)
+ })
+}
-export default semanticColors;
+export default semanticColors
diff --git a/packages/theme/src/tokens/semantic/backgrounds.js b/packages/theme/src/tokens/semantic/backgrounds.js
index 8011ebd2..66c36f57 100644
--- a/packages/theme/src/tokens/semantic/backgrounds.js
+++ b/packages/theme/src/tokens/semantic/backgrounds.js
@@ -4,7 +4,7 @@
* Generated from figma-reference-tokens-studio.
*/
-import { tokenRef } from '../build/refs.js';
+import { tokenRef } from '../build/refs.js'
export const backgroundSemantic = {
light: {
@@ -20,7 +20,8 @@ export const backgroundSemantic = {
warning: tokenRef('primitives.yellow.200'),
backdrop: tokenRef('#00000040'),
primaryHover: tokenRef('brand.primary.primary-600'),
- primary: tokenRef('brand.primary.primary-500')
+ primary: tokenRef('brand.primary.primary-500'),
+ primaryMask: tokenRef('#FE601F29')
},
dark: {
surfaceRaised: tokenRef('brand.surfaces.surface-800'),
@@ -35,10 +36,11 @@ export const backgroundSemantic = {
warning: tokenRef('primitives.yellow.800'),
backdrop: tokenRef('#00000040'),
primaryHover: tokenRef('brand.primary.primary-400'),
- primary: tokenRef('brand.primary.primary-500')
- },
-};
+ primary: tokenRef('brand.primary.primary-500'),
+ primaryMask: tokenRef('#FE601F29')
+ }
+}
export default {
- backgroundSemantic,
-};
+ backgroundSemantic
+}
diff --git a/packages/webkit/package.json b/packages/webkit/package.json
index 8703d4cd..1ae9bb40 100644
--- a/packages/webkit/package.json
+++ b/packages/webkit/package.json
@@ -73,6 +73,7 @@
"./empty-results-block": "./src/components/empty-results-block/empty-results-block.vue",
"./resizable-splitter": "./src/components/resizable-splitter/resizable-splitter.vue",
"./overline": "./src/components/overline/overline.vue",
+ "./box-grid-selection": "./src/components/box-grid-selection/box-grid-selection.vue",
"./accordion": "./src/core/primevue/accordion/accordion.vue",
"./accordion-tab": "./src/core/primevue/accordion-tab/accordion-tab.vue",
"./avatar": "./src/core/primevue/avatar/avatar.vue",
diff --git a/packages/webkit/src/components/box-grid-selection/box-grid-selection.vue b/packages/webkit/src/components/box-grid-selection/box-grid-selection.vue
new file mode 100644
index 00000000..9574604b
--- /dev/null
+++ b/packages/webkit/src/components/box-grid-selection/box-grid-selection.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.description }}
+
+
+
+
+
+
+
diff --git a/packages/webkit/src/components/box-grid-selection/package.json b/packages/webkit/src/components/box-grid-selection/package.json
new file mode 100644
index 00000000..fc41c090
--- /dev/null
+++ b/packages/webkit/src/components/box-grid-selection/package.json
@@ -0,0 +1,11 @@
+{
+ "main": "./box-grid-selection.vue",
+ "module": "./box-grid-selection.vue",
+ "types": "./box-grid-selection.vue.d.ts",
+ "browser": {
+ "./sfc": "./box-grid-selection.vue"
+ },
+ "sideEffects": [
+ "*.vue"
+ ]
+}
diff --git a/packages/webkit/src/core/card/card-box/card-box.vue b/packages/webkit/src/core/card/card-box/card-box.vue
index 8fecf5da..02785963 100644
--- a/packages/webkit/src/core/card/card-box/card-box.vue
+++ b/packages/webkit/src/core/card/card-box/card-box.vue
@@ -1,7 +1,5 @@
-