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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ All notable changes to the Ippon UI packages are documented in this file, so con

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), with one entry per release listing the affected package versions.

## 2026-07-08 — @ippon-ui/styles 0.0.10 · @ippon-ui/react 0.0.9

### Added

- `table` molecule: `-minimal` alternative on `ippon-table--header` and `ippon-table--cell` shrinks the column to its content width (`{ minimal: true }` on the mixins).
- `table` molecule: a body row can start with a row header (`ippon-table--header` as first cell); row headers are bold and follow the same border rules as cells.
- `title-display` atom: color alternatives, the same classes as `text` (e.g. `-color-brand-primary`, `-color-neutral-tertiary`), with a `color` option on the mixin.
- `IpponTitleDisplay` React component: display title with `tag` (`h1`/`h2`/`h3` drive the size), `size` and `color` props.

### Changed

- `title` and `title-display` atoms are never underlined, so they can be used as links (`<a>` tag) without extra styling.
- The Pattern Library documentation site is fully restyled with the Ippon UI design system (Ippon UI branding, components and tokens) and its home page documents the npm installation (`npm install -D @ippon-ui/styles`) alongside the stylesheet-link usage.

## 2026-07-08 — @ippon-ui/styles 0.0.9 · @ippon-ui/react 0.0.8

### Added
Expand Down
13 changes: 0 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions react/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@ippon-ui/react",
"description": "Ippon UI React Component Library",
"version": "0.0.8",
"version": "0.0.9",
"license": "Apache-2.0",
"repository": {
"type": "git",
Expand Down Expand Up @@ -39,7 +39,7 @@
},
"peerDependencies": {
"@ippon-ui/icons": "~0.0.2",
"@ippon-ui/styles": "~0.0.9",
"@ippon-ui/styles": "~0.0.10",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
Expand Down
43 changes: 43 additions & 0 deletions react/src/IpponTitleDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { IpponTokenTextColor } from './Tokens.ts';
import type { DataSelectableWithChildren } from './DataSelectable.ts';
import { clsx } from 'clsx';
import { optionalToAlternativeClass, optionalToPrefixedAlternativeClass } from './CAP.ts';
import type { JSX } from 'react';

type Size = 'large' | 'medium' | 'small';

type HeadingTag = 'h1' | 'h2' | 'h3';

type IpponTitleDisplayWithHeadingProps = DataSelectableWithChildren<{
tag: HeadingTag;
size?: Size;
color?: IpponTokenTextColor;
}>;

type IpponTitleDisplayWithNonHeadingProps = DataSelectableWithChildren<{
tag?: Exclude<keyof JSX.IntrinsicElements, HeadingTag>;
size: Size;
color?: IpponTokenTextColor;
}>;

type IpponTitleDisplayProps =
| IpponTitleDisplayWithHeadingProps
| IpponTitleDisplayWithNonHeadingProps;

export const IpponTitleDisplay = (props: IpponTitleDisplayProps) => {
const CustomTag: keyof JSX.IntrinsicElements = (props.tag ||
'div') as keyof JSX.IntrinsicElements;

return (
<CustomTag
className={clsx(
'ippon-title-display',
optionalToAlternativeClass(props.size),
optionalToPrefixedAlternativeClass('color')(props.color),
)}
data-selector={props.dataSelector}
>
{props.children}
</CustomTag>
);
};
1 change: 1 addition & 0 deletions react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ export { IpponProgress } from './IpponProgress.tsx';
export { IpponSeparator } from './IpponSeparator.tsx';
export { IpponText } from './IpponText.tsx';
export { IpponTitle } from './IpponTitle.tsx';
export { IpponTitleDisplay } from './IpponTitleDisplay.tsx';
export { IpponVSpace, IpponVSpaceSlot } from './IpponVSpace.tsx';
export { type DataSelectableWithChildren } from './DataSelectable.ts';
53 changes: 53 additions & 0 deletions react/stories/IpponTitleDisplay.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { Meta, StoryObj } from '@storybook/react-vite';
import { IpponTitleDisplay } from '../src/IpponTitleDisplay.tsx';

const meta = {
title: 'Atom/Title display',
component: IpponTitleDisplay,
args: {
tag: 'h1',
children: 'Display title',
},
argTypes: {
size: {
control: 'select',
options: [undefined, 'large', 'medium', 'small'],
},
color: {
control: 'select',
options: [
undefined,
'brand-primary',
'neutral-tertiary',
'success-primary',
'error-primary',
'warning-primary',
'information-primary',
],
},
},
} satisfies Meta<typeof IpponTitleDisplay>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {};

export const Sizes: Story = {
render: () => (
<>
<IpponTitleDisplay tag="h1">Large display (h1)</IpponTitleDisplay>
<IpponTitleDisplay tag="h2">Medium display (h2)</IpponTitleDisplay>
<IpponTitleDisplay tag="h3">Small display (h3)</IpponTitleDisplay>
</>
),
};

export const StyledAsSmall: Story = {
args: { tag: 'h1', size: 'small', children: 'h1 styled as small' },
};

export const Colored: Story = {
args: { tag: 'h2', color: 'brand-primary', children: 'Brand display title' },
};
103 changes: 103 additions & 0 deletions react/test/IpponTitleDisplay.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { beforeEach, describe, expect, it } from 'vitest';
import { render, screen, configure, cleanup } from '@testing-library/react';
import '@testing-library/jest-dom/vitest';
import { IpponTitleDisplay } from '../src';

configure({
testIdAttribute: 'data-selector',
});

describe('IpponTitleDisplay', () => {
beforeEach(cleanup);

describe('HTML Tags', () => {
it('should render as div by default', () => {
render(
<IpponTitleDisplay size="large" dataSelector="ippon-title-display">
Display title
</IpponTitleDisplay>,
);
const title = screen.getByTestId('ippon-title-display');
expect(title.tagName).toBe('DIV');
expect(title).toHaveClass('ippon-title-display');
});

it('should render as h1 when specified', () => {
render(
<IpponTitleDisplay tag="h1" dataSelector="ippon-title-display">
Display title
</IpponTitleDisplay>,
);
const title = screen.getByTestId('ippon-title-display');
expect(title.tagName).toBe('H1');
expect(title).toHaveClass('ippon-title-display');
});

it('should render as h2 when specified', () => {
render(
<IpponTitleDisplay tag="h2" dataSelector="ippon-title-display">
Display title
</IpponTitleDisplay>,
);
const title = screen.getByTestId('ippon-title-display');
expect(title.tagName).toBe('H2');
expect(title).toHaveClass('ippon-title-display');
});

it('should render as h3 when specified', () => {
render(
<IpponTitleDisplay tag="h3" dataSelector="ippon-title-display">
Display title
</IpponTitleDisplay>,
);
const title = screen.getByTestId('ippon-title-display');
expect(title.tagName).toBe('H3');
expect(title).toHaveClass('ippon-title-display');
});
});

describe('Sizes', () => {
it('should not have a size class by default', () => {
render(
<IpponTitleDisplay tag="h1" dataSelector="ippon-title-display">
Display title
</IpponTitleDisplay>,
);
const title = screen.getByTestId('ippon-title-display');
expect(title.className).toBe('ippon-title-display');
});

it.each(['large', 'medium', 'small'] as const)('should render %s size class', (size) => {
render(
<IpponTitleDisplay tag="h1" size={size} dataSelector="ippon-title-display">
Display title
</IpponTitleDisplay>,
);
const title = screen.getByTestId('ippon-title-display');
expect(title).toHaveClass('ippon-title-display', `-${size}`);
});
});

describe('Colors', () => {
it('should render the color class', () => {
render(
<IpponTitleDisplay tag="h1" color="brand-primary" dataSelector="ippon-title-display">
Display title
</IpponTitleDisplay>,
);
const title = screen.getByTestId('ippon-title-display');
expect(title).toHaveClass('ippon-title-display', '-color-brand-primary');
});
});

describe('Children', () => {
it('should render its children', () => {
render(
<IpponTitleDisplay tag="h1" dataSelector="ippon-title-display">
Display title
</IpponTitleDisplay>,
);
expect(screen.getByTestId('ippon-title-display')).toHaveTextContent('Display title');
});
});
});
26 changes: 0 additions & 26 deletions styles/logo.svg

This file was deleted.

3 changes: 1 addition & 2 deletions styles/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ippon-ui/styles",
"version": "0.0.9",
"version": "0.0.10",
"description": "Ippon UI Pattern Library",
"repository": {
"type": "git",
Expand Down Expand Up @@ -69,7 +69,6 @@
"stylelint-config-standard-scss": "17.0.0",
"stylelint-order": "8.1.1",
"stylelint-scss": "7.0.0",
"tikuidoc-tikui": "9.0.1",
"vitest": "4.1.4"
}
}
11 changes: 11 additions & 0 deletions styles/part/code.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.ippon-grid.-media-4.-media-desktop-s-12.-gap-16
.ippon-grid--slot.-col-4.-col-desktop-s-6
.ippon-v-space.-gap-8.-left
pre.ipp-doc-snippet
code.code.language-html !{ htmlCode }
button.ippon-button.-secondary.-small(onclick='copyCode(this)', data-code=htmlRaw) Copy
.ippon-grid--slot.-col-4.-col-desktop-s-6
.ippon-v-space.-gap-8.-left
pre.ipp-doc-snippet
code.code.language-pug !{ pugCode }
button.ippon-button.-secondary.-small(onclick='copyCode(this)', data-code=pugRaw) Copy
1 change: 1 addition & 0 deletions styles/part/component-render.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
iframe.ipp-doc-iframe(src=src, height=height, title='Component rendering')
5 changes: 5 additions & 0 deletions styles/part/component.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.ippon-card.-border
.ippon-v-space.-gap-16
.markdown !{ markdown }
.render !{ render }
.code !{ code }
1 change: 1 addition & 0 deletions styles/part/template-render.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a.ippon-button.-small(href=src, target='_blank') Show
5 changes: 5 additions & 0 deletions styles/part/template.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.ippon-card.-border
.ippon-v-space.-gap-16
.markdown !{ markdown }
.render !{ render }
.code !{ code }
Loading
Loading