Skip to content

Commit 0331922

Browse files
adamloblerclaude
andcommitted
feat(ui-card,ui,ui-scripts): add Card component with base and nested variants
Card is a wrapper for grouping related content. The variant prop (base | nested) and size prop (sm | md | lg) are its only two options. The base variant renders a background, border colour and elevation shadow; the nested variant is meant to sit inside a base Card and omits all three, using a smaller border radius. Each size drives its own padding, border radius and min/max width breakpoints. Built on the v11.7 token system (useStyleNew plus generated Card theme tokens) rather than a legacy per-component theme.ts, so it resolves tokens across all four themes. This requires instructure-design-tokens v1.6.0, the release that adds the Card token set. Exported from the @instructure/ui v11_7 entrypoint. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 30c7251 commit 0331922

19 files changed

Lines changed: 470 additions & 10 deletions

packages/__docs__/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"@instructure/ui-buttons": "workspace:*",
4747
"@instructure/ui-byline": "workspace:*",
4848
"@instructure/ui-calendar": "workspace:*",
49+
"@instructure/ui-card": "workspace:*",
4950
"@instructure/ui-checkbox": "workspace:*",
5051
"@instructure/ui-color-picker": "workspace:*",
5152
"@instructure/ui-color-utils": "workspace:*",

packages/__docs__/tsconfig.build.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@
6868
{
6969
"path": "../ui-calendar/tsconfig.build.json"
7070
},
71+
{
72+
"path": "../ui-card/tsconfig.build.json"
73+
},
7174
{
7275
"path": "../ui-checkbox/tsconfig.build.json"
7376
},

packages/ui-card/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
lib/
2+
.babel-cache/
3+
es/
4+
types/

packages/ui-card/.npmignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
**/.*
2+
**/__tests__
3+
**/__testfixtures__
4+
*.config.js
5+
*.conf.js

packages/ui-card/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Change Log
2+
3+
All notable changes to this project will be documented in this file.
4+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

packages/ui-card/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
## ui-card
2+
3+
[![npm][npm]][npm-url]
4+
[![MIT License][license-badge]][license]
5+
[![Code of Conduct][coc-badge]][coc]
6+
7+
### Components
8+
9+
The `ui-card` package contains the following:
10+
11+
- Card
12+
13+
### Installation
14+
15+
```sh
16+
npm install @instructure/ui-card
17+
```
18+
19+
[npm]: https://img.shields.io/npm/v/@instructure/ui-card.svg
20+
[npm-url]: https://npmjs.com/package/@instructure/ui-card
21+
[license-badge]: https://img.shields.io/npm/l/instructure-ui.svg?style=flat-square
22+
[license]: https://github.com/instructure/instructure-ui/blob/master/LICENSE.md
23+
[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square
24+
[coc]: https://github.com/instructure/instructure-ui/blob/master/CODE_OF_CONDUCT.md

packages/ui-card/babel.config.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2015 - present Instructure, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
module.exports = {
26+
presets: [
27+
[
28+
require('@instructure/ui-babel-preset'),
29+
{
30+
esModules: Boolean(process.env.ES_MODULES),
31+
removeConsole: process.env.NODE_ENV === 'production',
32+
transformImports: Boolean(process.env.TRANSFORM_IMPORTS)
33+
}
34+
]
35+
]
36+
}

packages/ui-card/package.json

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"name": "@instructure/ui-card",
3+
"version": "11.7.4",
4+
"description": "A basic wrapper component for grouping content with padding, border radius, shadow, and background.",
5+
"author": "Instructure, Inc. Engineering and Product Design",
6+
"module": "./es/index.js",
7+
"main": "./lib/index.js",
8+
"types": "./types/index.d.ts",
9+
"repository": {
10+
"type": "git",
11+
"url": "https://github.com/instructure/instructure-ui.git"
12+
},
13+
"homepage": "https://instructure.github.io/instructure-ui/",
14+
"bugs": "https://github.com/instructure/instructure-ui/issues",
15+
"scripts": {
16+
"lint": "ui-scripts lint",
17+
"lint:fix": "ui-scripts lint --fix",
18+
"clean": "ui-scripts clean",
19+
"build": "ui-scripts build --modules es,cjs",
20+
"build:watch": "pnpm run ts:check -- --watch & ui-scripts build --watch",
21+
"build:types": "tsc -p tsconfig.build.json",
22+
"ts:check": "tsc -p tsconfig.build.json --noEmit --emitDeclarationOnly false"
23+
},
24+
"license": "MIT",
25+
"dependencies": {
26+
"@babel/runtime": "^7.29.7",
27+
"@instructure/emotion": "workspace:*",
28+
"@instructure/shared-types": "workspace:*",
29+
"@instructure/ui-react-utils": "workspace:*",
30+
"@instructure/ui-themes": "workspace:*"
31+
},
32+
"devDependencies": {
33+
"@instructure/ui-axe-check": "workspace:*",
34+
"@instructure/ui-babel-preset": "workspace:*",
35+
"@testing-library/jest-dom": "^6.9.1",
36+
"@testing-library/react": "16.3.2",
37+
"vitest": "^4.1.9"
38+
},
39+
"peerDependencies": {
40+
"react": ">=18 <=19"
41+
},
42+
"publishConfig": {
43+
"access": "public"
44+
},
45+
"sideEffects": false,
46+
"exports": {
47+
"./lib/*": "./lib/*",
48+
"./es/*": "./es/*",
49+
"./types/*": "./types/*",
50+
"./package.json": "./package.json",
51+
"./src/*": "./src/*",
52+
".": {
53+
"src": "./src/exports/a.ts",
54+
"types": "./types/exports/a.d.ts",
55+
"import": "./es/exports/a.js",
56+
"require": "./lib/exports/a.js",
57+
"default": "./es/exports/a.js"
58+
},
59+
"./v11_7": {
60+
"src": "./src/exports/a.ts",
61+
"types": "./types/exports/a.d.ts",
62+
"import": "./es/exports/a.js",
63+
"require": "./lib/exports/a.js",
64+
"default": "./es/exports/a.js"
65+
},
66+
"./latest": {
67+
"src": "./src/exports/a.ts",
68+
"types": "./types/exports/a.d.ts",
69+
"import": "./es/exports/a.js",
70+
"require": "./lib/exports/a.js",
71+
"default": "./es/exports/a.js"
72+
}
73+
}
74+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2015 - present Instructure, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
import { useStyleNew } from '@instructure/emotion'
25+
import { passthroughProps } from '@instructure/ui-react-utils'
26+
27+
import type { CardProps } from './props.js'
28+
import generateStyle from './styles.js'
29+
30+
/**
31+
---
32+
category: components
33+
---
34+
**/
35+
const Card = ({
36+
children,
37+
variant = 'base',
38+
size = 'md',
39+
themeOverride,
40+
...rest
41+
}: CardProps) => {
42+
const styles = useStyleNew({
43+
generateStyle,
44+
themeOverride,
45+
params: { variant, size },
46+
componentId: 'Card',
47+
displayName: 'Card'
48+
})
49+
50+
return (
51+
<div {...passthroughProps(rest)} css={styles?.card}>
52+
{children}
53+
</div>
54+
)
55+
}
56+
57+
export default Card
58+
export { Card }
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2015 - present Instructure, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
import type { ReactNode } from 'react'
26+
import type { ComponentStyle, NewThemeOverrideProp } from '@instructure/emotion'
27+
import type { OtherHTMLAttributes } from '@instructure/shared-types'
28+
import type { NewComponentTypes } from '@instructure/ui-themes'
29+
30+
type CardOwnProps = {
31+
/**
32+
* The content to be rendered inside the Card
33+
*/
34+
children?: ReactNode
35+
/**
36+
* `base` renders a background, border color, and shadow. `nested` is
37+
* meant to be placed inside a `base` Card and omits the background,
38+
* border color, and shadow.
39+
*/
40+
variant?: 'base' | 'nested'
41+
/**
42+
* `sm` applies a max-width, `md` applies a min- and max-width, and `lg`
43+
* applies a min-width, each based on breakpoint tokens. Padding and
44+
* border radius also scale per size.
45+
*/
46+
size?: 'sm' | 'md' | 'lg'
47+
}
48+
49+
type PropKeys = keyof CardOwnProps
50+
51+
type AllowedPropKeys = Readonly<Array<PropKeys>>
52+
53+
type CardProps = CardOwnProps &
54+
NewThemeOverrideProp<ReturnType<NewComponentTypes['Card']>> &
55+
OtherHTMLAttributes<CardOwnProps>
56+
57+
type CardStyle = ComponentStyle<'card'>
58+
59+
const allowedProps: AllowedPropKeys = ['children', 'variant', 'size']
60+
61+
export type { CardProps, CardStyle }
62+
export { allowedProps }

0 commit comments

Comments
 (0)