Skip to content

Commit

Permalink
feat: alert
Browse files Browse the repository at this point in the history
  • Loading branch information
azuradara committed Jan 9, 2025
1 parent 8d60958 commit 09dbe18
Show file tree
Hide file tree
Showing 10 changed files with 1,641 additions and 35 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/chroma.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Build

on:
push:
paths:
- 'packages/**'

jobs:
chroma:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: 20

- uses: pnpm/action-setup@v2
name: Install pnpm
with:
version: 9
run_install: false

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm i --frozen-lockfile

- name: Run Chromatic
uses: chromaui/action@latest
with:
workingDir: packages/celeste-vue
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ node_modules
dist
.eslintcache
.DS_Store
storybook-static
*storybook.log
50 changes: 50 additions & 0 deletions packages/celeste-vue/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { PathLike } from 'node:fs';
import { dirname, join, resolve } from 'node:path';

function getAbsolutePath(value): PathLike {
return dirname(require.resolve(join(value, 'package.json')));
}

/** @type { import('@storybook/vue3-vite').StorybookConfig } */
const config = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
getAbsolutePath('@storybook/addon-onboarding'),
getAbsolutePath('@storybook/addon-essentials'),
getAbsolutePath('@chromatic-com/storybook'),
getAbsolutePath('@storybook/addon-interactions'),
],
framework: {
name: getAbsolutePath('@storybook/vue3-vite'),
options: {
docgen: 'vue-component-meta',
},
},
docs: {
autodocs: true,
},
async viteFinal(config) {
config.resolve = config.resolve || {};
config.resolve.alias = config.resolve.alias || {};

config.resolve.alias = {
...config.resolve.alias,
'@': resolve(__dirname, '../src'),
'vue': `${getAbsolutePath('vue')}/dist/vue.runtime.esm-bundler.js`,
'@vue/runtime-dom': `${getAbsolutePath('@vue/runtime-dom')}/dist/runtime-dom.esm-bundler.js`,
'@vue/runtime-core': `${getAbsolutePath('@vue/runtime-core')}/dist/runtime-core.esm-bundler.js`,
};

config.plugins = config.plugins || [];
config.plugins.push(await import('unocss/vite'));

config.optimizeDeps = {
...config.optimizeDeps,
include: [...(config.optimizeDeps?.include || []), 'vue'],
};

return config;
},
};

export default config;
17 changes: 17 additions & 0 deletions packages/celeste-vue/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Preview } from '@storybook/vue3';

import 'virtual:uno.css';
import '@youcan/celeste-tokens/tokens.css';

const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;
6 changes: 6 additions & 0 deletions packages/celeste-vue/chromatic.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"onlyChanged": true,
"projectId": "Project:677f37bbe9cfbdfdf743f0ab",
"storybookBaseDir": "packages/celeste-vue",
"zip": true
}
16 changes: 15 additions & 1 deletion packages/celeste-vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
"type-check": "vue-tsc -p tsconfig.check.json --noEmit",
"type-gen": "vue-tsc --declaration --emitDeclarationOnly",
"test": "vitest",
"release": "pnpm publish --access public"
"release": "pnpm publish --access public",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"@youcan/celeste-icons": "workspace:*",
Expand All @@ -28,17 +30,29 @@
"radix-vue": "^1.9.12"
},
"devDependencies": {
"@chromatic-com/storybook": "^3.2.3",
"@storybook/addon-essentials": "^8.4.7",
"@storybook/addon-interactions": "^8.4.7",
"@storybook/addon-onboarding": "^8.4.7",
"@storybook/blocks": "^8.4.7",
"@storybook/test": "^8.4.7",
"@storybook/vue3": "^8.4.7",
"@storybook/vue3-vite": "^8.4.7",
"@tsconfig/node20": "^20.1.4",
"@types/jsdom": "^21.1.7",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/test-utils": "^2.4.6",
"@vue/tsconfig": "^0.7.0",
"chromatic": "^11.22.1",
"jsdom": "^25.0.1",
"sass": "^1.83.1",
"storybook": "^8.4.7",
"unocss": "^0.65.4",
"vite": "^6.0.7",
"vite-plugin-dts": "^4.4.0",
"vitest": "^2.1.8",
"vue": "^3.5.13",
"vue-docgen-api": "^4.79.2",
"vue-tsc": "^2.2.0"
}
}
153 changes: 153 additions & 0 deletions packages/celeste-vue/src/components/alert/alert.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue';
import clsx from 'clsx';
import { ref, watchEffect } from 'vue';
const props = withDefaults(
defineProps<AlertProps>(),
{ size: 'xs', variant: 'fill', state: 'information' },
);
// TODO: find a better way of doing this bs, maybe iconify
const ICON_MAP: Record<NonNullable<AlertProps['state']>, string> = {
error: 'IconAlertFill',
feature: 'IconMagicFill',
warning: 'IconErrorWarningFill',
success: 'IconCheckboxCircleFill',
information: 'IconInformationFill',
};
const icon = ref();
watchEffect(async () => {
icon.value = (await import('@youcan/celeste-icons'))[ICON_MAP[props.state]];
});
</script>

<script lang="ts">
interface AlertProps {
class?: HTMLAttributes['class'];
size?: 'xs' | 'sm' | 'lg';
variant?: 'fill' | 'light' | 'lighter' | 'stroke';
state?: 'information' | 'success' | 'warning' | 'error' | 'feature';
}
</script>

<template>
<div
role="alert"
class="celeste-alert"
:class="clsx(
`celeste-alert--${size}`,
`celeste-alert--${variant}--${state}`,
props.class,
)"
>
<component
:is="icon"
class="celeste-alert-icon"
:class="`celeste-alert-icon--${variant}--${state}`"
/>
<slot />
</div>
</template>

<style lang="scss" scoped>
@use 'sass:map';
$alert-sizes: (
'xs': (
height: 32px,
padding: 8px,
gap: 8px,
),
'sm': (
height: 36px,
padding: 8px 10px,
gap: 8px,
),
'lg': (
height: fit-content,
padding: 14px,
gap: 12px,
),
);
$alert-styles: (
'fill': 'base',
'light': 'light',
'lighter': 'lighter',
);
$alert-states: ('error' 'feature' 'warning' 'success' 'information');
@mixin alert-size($size) {
$size-props: map.get($alert-sizes, $size);
height: map.get($size-props, height);
padding: map.get($size-props, padding);
gap: map.get($size-props, gap);
}
@mixin alert-style($style, $state) {
@if $style == 'stroke' {
border: 1px solid var(--color-stroke-soft-200);
background-color: var(--color-bg-white-0);
color: var(--color-text-strong-950);
box-shadow: var(--shadow-regular-md);
} @else {
border: none;
background-color: var(--color-state-#{$state}-#{map.get($alert-styles, $style)});
color: if($style == 'fill', var(--color-static-white), var(--color-text-strong-950));
}
}
@mixin icon-style($style, $state) {
@if $style == 'fill' {
color: var(--color-static-white);
} @else {
color: var(--color-state-#{$state}-base);
}
}
.celeste-alert {
width: 100%;
display: flex;
align-items: center;
border-radius: var(--radius-8);
font: var(--paragraph-xs);
box-sizing: border-box;
&-icon {
height: 16px;
width: 16px;
@each $style in ('fill', 'light', 'lighter', 'stroke') {
@each $state, $icon in $alert-states {
&--#{$style}--#{$state} {
@include icon-style($style, $state);
}
}
}
}
&--xs {
@include alert-size('xs');
}
&--sm {
@include alert-size('sm');
}
&--lg {
@include alert-size('lg');
}
@each $style in ('fill', 'light', 'lighter', 'stroke') {
@each $state in $alert-states {
&--#{$style}--#{$state} {
@include alert-style($style, $state);
}
}
}
}
</style>
25 changes: 25 additions & 0 deletions packages/celeste-vue/src/components/alert/stories/alert.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Meta, StoryObj } from '@storybook/vue3';
import Alert from '../alert.vue';

const meta: Meta<typeof Alert> = {
title: 'Components/Alert',
component: Alert,
};

export default meta;

type Story = StoryObj<typeof Alert>;

export const Default: Story = {
render: args => ({
components: { Alert },
setup() {
return { args };
},
template: `
<Alert v-bind="args">
This is an alert.
</Alert>
`,
}),
};
3 changes: 2 additions & 1 deletion packages/celeste-vue/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ export default defineConfig({
},
build: {
lib: {
formats: ['es'],
name: 'celeste',
fileName: (format, name) => `${name}.${format === 'es' ? 'js' : 'umd.cjs'}`,
entry: {
index: resolve(__dirname, 'src/index.ts'),
},
},
rollupOptions: {
external: ['vue'],
external: ['vue', '@vue/runtime-core'],
output: {
globals: {
vue: 'Vue',
Expand Down
Loading

0 comments on commit 09dbe18

Please sign in to comment.