Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ package-lock.json
/coverage/

/lib/
tsconfig.tsbuildinfo
tsconfig.tsbuildinfo
*storybook.log
83 changes: 83 additions & 0 deletions .storybook/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* From https://www.joshwcomeau.com/css/custom-css-reset/ */

/* 1. Use a more-intuitive box-sizing model */
*,
*::before,
*::after {
box-sizing: border-box;
}

/* 2. Remove default margin */
* {
margin: 0;
}

/* 3. Enable keyword animations */
@media (prefers-reduced-motion: no-preference) {
html {
interpolate-size: allow-keywords;
}
}

body {
/* 4. Add accessible line-height */
line-height: 1.5;
/* 5. Improve text rendering */
-webkit-font-smoothing: antialiased;
}

/* 6. Improve media defaults */
img,
picture,
video,
canvas,
svg {
display: block;
max-width: 100%;
}

/* 7. Inherit fonts for form controls */
input,
button,
textarea,
select {
font: inherit;
}

/* 8. Avoid text overflows */
p,
h1,
h2,
h3,
h4,
h5,
h6 {
overflow-wrap: break-word;
}

/* 9. Improve line wrapping */
p {
text-wrap: pretty;
}
h1,
h2,
h3,
h4,
h5,
h6 {
text-wrap: balance;
}

/*
10. Create a root stacking context
*/
#root,
#__next {
isolation: isolate;
}

/* Storybook */

* {
font-family: "Mulish", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
25 changes: 25 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { StorybookConfig } from '@storybook/react-vite'

const config: StorybookConfig = {
stories: [
'../src/**/*.mdx',
'../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',
],
addons: [
{
name: '@storybook/addon-essentials',
options: {
docs: false,
},
},
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
core: {
disableTelemetry: true,
},
}
export default config
5 changes: 5 additions & 0 deletions .storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Mulish:wght@300;600&display=swap"
rel="stylesheet"
/>
15 changes: 15 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Preview } from '@storybook/react'
import './global.css'

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

export default preview
8 changes: 8 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import javascript from '@eslint/js'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import storybook from 'eslint-plugin-storybook'
import globals from 'globals'
import typescript from 'typescript-eslint'

Expand Down Expand Up @@ -59,6 +60,7 @@ export default typescript.config(
'no-useless-return': 'error',
'no-var': 'error',
'object-curly-spacing': ['error', 'always'],
'object-shorthand': 'error',
'prefer-const': 'warn',
'prefer-destructuring': ['warn', {
object: true,
Expand Down Expand Up @@ -104,5 +106,11 @@ export default typescript.config(
...globals.node,
},
},
},
{
extends: [
...storybook.configs['flat/recommended'],
],
files: ['**/*.stories.tsx'],
}
)
14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"prepublishOnly": "npm run build",
"serve": "node bin/cli.js",
"preserve": "npm run build",
"storybook": "storybook dev -p 6006",
"test": "vitest run",
"typecheck": "tsc --noEmit",
"url": "run-p -l watch:ts watch:vite watch:url",
Expand All @@ -61,6 +62,12 @@
},
"devDependencies": {
"@eslint/js": "9.24.0",
"@storybook/addon-essentials": "8.6.12",
"@storybook/addon-interactions": "8.6.12",
"@storybook/blocks": "8.6.12",
"@storybook/react": "8.6.12",
"@storybook/react-vite": "8.6.12",
"@storybook/test": "8.6.12",
"@testing-library/react": "16.3.0",
"@types/node": "22.14.0",
"@types/react": "19.1.0",
Expand All @@ -71,13 +78,20 @@
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "5.2.0",
"eslint-plugin-react-refresh": "0.4.19",
"eslint-plugin-storybook": "0.12.0",
"globals": "16.0.0",
"jsdom": "26.0.0",
"nodemon": "3.1.9",
"npm-run-all": "4.1.5",
"storybook": "8.6.12",
"typescript": "5.8.3",
"typescript-eslint": "8.29.1",
"vite": "6.2.5",
"vitest": "3.1.1"
},
"eslintConfig": {
"extends": [
"plugin:storybook/recommended"
]
}
}
6 changes: 3 additions & 3 deletions src/components/Cell/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import Breadcrumb from '../Breadcrumb/Breadcrumb.js'
import Layout from '../Layout/Layout.js'

interface CellProps {
source: FileSource;
row: number;
col: number;
source: FileSource
row: number
col: number
}

/**
Expand Down
97 changes: 97 additions & 0 deletions src/components/Dropdown/Dropdown.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
.dropdown {
display: inline-block;
position: relative;
text-overflow: ellipsis;
user-select: none;
white-space: nowrap;
}

.dropdownButton,
.dropdownButton:active,
.dropdownButton:focus,
.dropdownButton:hover {
align-items: center;
background: inherit;
border: none;
color: inherit;
cursor: pointer;
display: flex;
font-size: initial;
overflow-x: hidden;
padding: 0;
}
.dropdownButton:active,
.dropdownButton:focus,
.dropdownButton:hover {
color: #113;
}

/* caret */
.dropdownButton::before {
content: "\25bc";
display: inline-block;
font-size: 10px;
margin-right: 4px;
transform: rotate(-90deg);
transition: transform 0.1s;
}
.dropdown:has([aria-expanded="true"]) .dropdownButton::before {
transform: rotate(0deg);
}

/* alignment */
.dropdownLeft .dropdownContent {
left: 0;
}

.dropdownContent {
background-color: #eee;
position: absolute;
right: 0;
border-radius: 6px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
display: flex;
flex-direction: column;
max-height: 0;
max-width: 300px;
min-width: 160px;
transition: max-height 0.1s ease-out;
overflow-y: hidden;
z-index: 20;
}

.dropdown:has([aria-expanded="true"]) .dropdownContent {
max-height: 170px;
overflow-y: auto;
}

.dropdownContent > * {
display: block;
}

.dropdownContent a,
.dropdownContent button {
background: none;
border: none;
border-radius: 0;
color: inherit;
flex-shrink: 0;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
padding: 8px 16px;
text-align: left;
text-decoration: none;
width: 100%;
}
.dropdownContent a:active,
.dropdownContent a:focus,
.dropdownContent a:hover,
.dropdownContent button:active,
.dropdownContent button:focus,
.dropdownContent button:hover {
background-color: rgba(31, 30, 33, 0.1);
}
.dropdownContent input {
margin: 4px 8px;
}
42 changes: 42 additions & 0 deletions src/components/Dropdown/Dropdown.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { Meta, StoryObj } from '@storybook/react'
import Dropdown from './Dropdown.js'

const meta: Meta<typeof Dropdown> = {
component: Dropdown,
}
export default meta
type Story = StoryObj<typeof Dropdown>;
export const Default: Story = {
args: {
label: 'Menu',
children: <>
<button>Item 1</button>
<button>Item 2</button>
<button>Item 3</button>
</>,
},
}

export const LeftAlign: Story = {
args: {
label: 'Menu',
align: 'left',
children: <>
<button>Item 1</button>
<button>Item 2</button>
<button>Item 3</button>
</>,
},
}

export const RightAlign: Story = {
args: {
label: 'Very long label for the menu',
align: 'right',
children: <>
<button>Item 1</button>
<button>Item 2</button>
<button>Item 3</button>
</>,
},
}
Loading